반응형
문제 링크 : https://leetcode.com/problems/move-pieces-to-obtain-a-string/
문제 설명 :
start라는 string에서, "L"은 왼쪽으로, "R"은 오른쪽으로 이동할 수 있습니다.
start에서 target으로 이동할 수 있는지를 False, True를 통해서 return 하세요.
예시)
1. input :
start = "_L__R__R_", target = "L______RR"
output: True
2. input:
start = "R_L_", target = "__LR"
output: False
3. input:
start = "_R", target = "R_"
output: False
접근방법 : 처음에는 start 스트링을 수정하거나, 리스트로 바꿔서 하려고 했었는데,
while 이나 for loop를 돌면서 그 안에서 pop 하는 방법이 굉장히 어렵다는 것을 깨달았습니다.
Time Limit Exceeded 가 걸리기는 했지만, 8개의 test case를 통과한 솔루션을 작성하기는 하였습니다.
새로 리스트를 두 개를 만들어서, "_"언더스코어를 제외한 값들을 넣어주고,
두 개를 비교하는 방법을 사용하면서, 인덱스를 같이 넣어주면서 start의 index와 target의 index를 비교하면 valid 여부를 쉽게 판단할 수 있습니다.
class Solution:
def canChange(self, start: str, target: str) -> bool:
n = len(start)
s_list, t_list = [], []
for i in range(n):
if start[i] != "_":
s_list.append((start[i], i))
if target[i] != "_":
t_list.append((target[i], i))
if len(s_list) != len(t_list):
return False
for i in range(len(s_list)):
if s_list[i][0] != t_list[i][0]:
return False
elif s_list[i][0] == "L" and s_list[i][1] < t_list[i][1]:
return False
elif s_list[i][0] == "R" and s_list[i][1] > t_list[i][1]:
return False
return True
아래는 삽질의 결과...
class Solution:
def canChange(self, start: str, target: str) -> bool:
n = len(start)
start_l, start_r = [0] * n, [0] * n
target_l, target_r = [0] * n, [0] * n
result_l, result_r = [0] * n, [0] * n
for i in range(n):
if start[i] == "L":
start_l[i] = 1
if start[i] == "R":
start_r[i] = 1
if target[i] == "L":
target_l[i] = 1
result_l[i] = 1
if target[i] == "R":
target_r[i] = 1
result_r[i] = 1
if not (sum(start_l) == sum(target_l) and sum(start_r) == sum(target_r)):
return False
l_count, r_count = sum(start_l), sum(start_r)
for i in range(n):
if start_l[i] == 1:
target_i = i
while target_i >= 0 and (result_l[target_i] != 1 and target_r[target_i] != 1):
if (result_l[target_i] == 1 or target_r[target_i] == 1):
break
target_i -= 1
# print(i, target_i)
if target_i >= 0 and result_l[target_i] == 1:
# target_l[target_i] -= 1
# start_l[i] -= 1
result_l[target_i] -= 1
for i in range(n-1, -1, -1):
if start_r[i] == 1:
target_i = i
while target_i < n and (result_r[target_i] != 1 and target_l[target_i] != 1):
if (result_r[target_i] == 1 or target_l[target_i] == 1):
break
target_i += 1
if target_i < n and result_r[target_i] == 1:
# target_r[target_i] -= 1
# start_r[i] -= 1
result_r[target_i] -= 1
# print(start_l, start_r, target_l, target_r)
# print(result_l, result_r)
if sum(result_l) == 0 and sum(result_r) == 0:
return True
한줄평 : 인덱스값을 활용하고, 언제나 원본 스트링 (또는 리스트)를 수정할 필요가 없다!
반응형
'알고리즘 > 리트코드' 카테고리의 다른 글
3071. Minimum Operations to Write the Letter Y on a Grid (0) | 2024.03.05 |
---|---|
3070. Count Submatrices with Top-Left Element and Sum Less Than k (0) | 2024.03.05 |
Leetcode Weekly Contest 311 (2022.09.18) (2413~2416) (0) | 2022.09.18 |
Weekly Contest 305. (2367~2370) (list, graph, dp) (0) | 2022.08.07 |