import heapq
class Solution:
def prevPermOpt1(self, arr: List[int]) -> List[int]:
h = []
heapq.heappush(h, [arr[-1], -len(arr)+1, len(arr)-1])
for i in range(len(arr)-2, -1, -1):
if arr[i] > h[0][0]:
target = []
while h and h[0][0] < arr[i]:
target = heapq.heappop(h)
arr[i], arr[target[2]] = arr[target[2]], arr[i]
return arr
else:
heapq.heappush(h, [arr[i],-i, i])
return arr
내 풀이 방법은 매우 직관적이다.
[값, -인덱스, 인덱스]
로 heap에 저장하여 관리한다.class Solution:
def prevPermOpt1(self, arr: List[int]) -> List[int]:
ind = -1
for i in range(len(arr)-1,0,-1):
if arr[i-1]>arr[i]:
ind = i-1
break
else:
return arr
for i in range(len(arr)-1,ind,-1):
if arr[i]<arr[ind] and arr[i]!=arr[i-1]:
arr[i],arr[ind] = arr[ind],arr[i]
break
return arr
개인적으로는 이 풀이가 매우 인상적이었다. 이렇게 생각한 것이 신기해서 한번 소개해 보겠습니다.
일단 처음 for문으로 i-1
의 값과 비교하여 i
의 값이 작은 i
를 ind
에 저장하고 for문을 나옵니다.
for문이 break에 걸리지 않고 모두 실행 된다면 이미 가장 사전상 가장 작은 수로 배치된 배열이므로 그대로 리턴합니다.
len(arr)-
~ind+1
로 index를 탐색하면서 arr[ind]
값 보다 작은 값이 나오면 바로 ind
와 값을 스왑하고 arr을 return합니다.
이렇게 되는 이유는 우리가 첫 for문에서 확인 했던것 때문인데
[1,1,1,1,4,3,3,3,3] 이린식의 배열이 있으면 ind
의 값은 4가 된다.
[1,1,1,1,4,1,2,3,4] 이런식으로 배열이 있어도 ind
의 값은 4가 된다.
[1,1,1,1,4,3,1,2,4] 이널식이면 ind
의 값은 3이 된다.
즉, ind
의 값은 배열을 뒤에서 부터 탐색할때 값이 커지는 가장 첫 번째 index이며 배열 가장 뒷 숫자는 ind
보다 큰 index들 중 가장 크거나 같은 숫자라는 것입니다.
그래서 arr[ind]
보다 작은 수가 나타나면 바로 스왑하는 것입니다.
하지만 같은 수가 연속으로 나와있다면 가장 가까운 index와 스왑하는 것이 올바르므로 예외처리 해주었습니다.