class Solution:
def knightDialer(self, n: int) -> int:
#n=3131
d = {-1: range(10), 0: [4,6], 1: [6,8], 2: [7,9], 3: [4,8], 4: [0,3,9], 5: [],
6: [0,1,7], 7: [2,6], 8: [1,3], 9: [2,4]}
cache = {}
def dp(n, path):
if n == 0:
return 1
key = (n, path)
if key in cache:
return cache[key]
count = 0
for _next in d[path]:
count += dp(n-1, _next)
cache[key] = count
return cache[key]
s = dp(n, -1) % (10**9+7)
#print(cache)
return s
근데 이게 통과는 하는데 그렇게 빠르지는 않다. 와 근데 얘는 천재인듯.
https://leetcode.com/problems/knight-dialer/discuss/189252/O(logN) 첫번째 O(N) time, O(1) space 인 코드도 dp이긴 한데 저렇게 쉽게 풀어써버리네..
503 https://leetcode.com/problems/next-greater-element-ii/
바로 이전글에서 monotonic이라는 증가하는 스택을 언급했었는데 예시 문제가 바로 나왔다. 문제에 예시가 부족해서 애매한 부분을 이해하기가 힘들었다. [1,2,3,4,3]의 경우 [2,3,4,-1,4]인데 이것은 '현재 인덱스의 숫자보다 큰 숫자이면서 오른쪽에 있는 숫자를 가져오는거다.'
그러니까.. [5,4,3,2,1]이면 [-1,5,4,3,2]가 아니라 [-1,5,5,5,5]라는거다. (나같은경우 단순히 현재 인덱스의 숫자보다 더큰 최소 숫자의 인덱스를 리턴하는것으로 이해했는데 이게 아님.)
이걸 해결하려면 [5,4,3,2,1]같은경우 한번 더 붙여서[5,4,3,2,1,5,4,3,2,1]로 만든 후에 %로 인덱스를 조정하면서 monotonic stack을 만들어서 풀면 된다.
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
len_nums = len(nums)
ret = [-1]*len_nums
stack = []
for i in range(len_nums * 2):
while stack and stack[-1][0] < nums[i % len_nums]:
ret[stack.pop()[1]] = nums[i % len_nums]
stack.append([nums[i % len_nums], i % len_nums])
return ret
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
l,r = 0,0
ret = 0
while r < len(nums):
if nums[r] == 0:
if k > 0: # k가 남아있으면 k를 쓴다.
k -= 1
else:
while nums[l] != 0: # l위치가 0이면 1까지 그냥 지나가준다.
l += 1
l += 1
ret = max(ret, r-l+1) # 최대 넓이를 매번 갱신해준다.
r += 1
return ret
class Solution:
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
#s="abaccc"
#k=2
l,r = 0,0
d = {}
ret = 0
while r < len(s):
d[s[r]] = r # 현재 단어 s[r]의 최신 위치를 계속 갱신해준다.
if len(d) > k: # 윈도우보다 커지면 가장 처음에 삽입되었던(인덱스가 가장 앞쪽의) 문자를 뺀다.
# 그리고 빠진 문자의 인덱스가 윈도우의 왼쪽이다.
c, l = sorted(d.items(), key=lambda x: x[1])[0]
del d[c]
l += 1
ret = max(ret, r-l+1) # 윈도우의 왼쪽과 오른쪽 길이를 잰다.
r += 1
return ret