LeetCode Problems/Medium

๐Ÿง‘๐Ÿป‍๐Ÿ’ป LeetCode Medium Collections 2 - 20 Problems

metamong 2024. 10. 31.

0054. Spiral Matrix / 0739. Daily Temperatures

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        e,s,w,n = [0,1], [1,0], [0,-1], [-1,0]
        output = []
        rows, cols = len(matrix), len(matrix[0])
        visited = [[False] * cols for _ in range(rows)]
        cnt = 0
        x, y = 0,0
        dirs = [e,s,w,n]
        dir_i = 0
        while True:
            visited[x][y] = True
            output.append(matrix[x][y])
            cnt+=1
            if cnt == rows*cols:
                break

            nx,ny = x+dirs[dir_i][0], y+dirs[dir_i][1]
            #as it goes
            if 0<=nx<rows and 0<=ny<cols:
                if not visited[nx][ny]:
                    x,y=nx,ny
                    continue
            
            #change dir
            dir_i += 1
            if dir_i == 4: dir_i = 0
            nx,ny = x+dirs[dir_i][0], y+dirs[dir_i][1]
            x,y=nx,ny
            continue

        
        return output
class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        stack = [(temperatures[0],0)]
        answer = [0]*(len(temperatures))
        for x in range(1,len(temperatures)):
            temp = temperatures[x]
            while stack:
                if stack[-1][0] < temp:
                    popped = stack.pop()
                    answer[popped[1]] = (x-popped[1])
                else:
                    break
            stack.append((temp,x))
        return answer

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0054) ์ „ํ˜•์ ์ธ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฌธ์ œ. ๋ฐฉํ–ฅ ๋ฒกํ„ฐ ๋™ / ๋‚จ / ์„œ / ๋ถ ๊ฐ๊ฐ ๋งŒ๋“ค๊ณ , dirs ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค์–ด ๋„ฃ๋Š”๋‹ค. ๋ฐฉํ–ฅ ๋ฐ”๊พธ๋Š” ์กฐ๊ฑด (1) ๋ฐฐ์—ด์˜ ๋๊นŒ์ง€ ๋‹ฟ๋Š” ๊ฒฝ์šฐ + (2) ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๊ณณ์„ ๋ฐฉ๋ฌธํ•œ ๊ฒฝ์šฐ: ์ด 2๊ฐ€์ง€ ์กฐ๊ฑด๋งŒ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด x,y update / ๊ทธ๋ ‡์ง€ ์•Š๋Š”๋‹ค๋ฉด dir ๋ฐฉํ–ฅ ๋ฐ”๊ฟ”์„œ ํ™•์ธ.

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0739) ๊ฐ์†Œํ•˜๋Š” monotonic stack์„ ์œ ์ง€ํ•˜๋ฉฐ answer updateํ•˜๋Š” monotonic stack ์œ ํ˜•

: ํ˜„์žฌ ์œ„์น˜์—์„œ ์ดํ›„ ์›์†Œ ์ค‘ ์ฒ˜์Œ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ์˜จ๋„๊ฐ€ ์žˆ์„ ๋•Œ ๊ทธ ์‚ฌ์ด์˜ ๋‚  ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ. ๊ทธ๋Ÿฌ๋ฉด ์ฆ๊ฐ€์ธ์ง€ ์•Œ์•„๋ณด๋Š” ์›์†Œ์™€, ๋‚  ์ˆ˜๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ์›์†Œ์˜ index ์ •๋ณด๊นŒ์ง€ 2๊ฐœ์˜ ์ •๋ณด๋ฅผ tuple๋กœ ์ €์žฅํ•ด ๊ตฌํ˜„ํ•˜๋Š” ์œ ํ˜•์„ ์ƒ๊ฐํ•ด์•ผ ํ•œ๋‹ค. ์ฆ๊ฐ€์ผ ๊ฒฝ์šฐ ๊ทธ ์•ž์„  ์›์†Œ๋“ค(while stack)์—์„œ ๋„ฃ๊ณ ์ž ํ•˜๋Š” ์›์†Œ๋ณด๋‹ค ์ž‘์€ ์ˆซ์ž๊ฐ€ ํฌํ•จ๋œ ์›์†Œ๋ฅผ ๋ชจ๋‘ ์ฐจ๋ก€๋Œ€๋กœ ๋นผ์„œ index๊ฐ„ ์ฐจ์ด๋กœ ๋‚  ์ˆ˜๋ฅผ answer์— update. ๊ฒฐ๋ก ์ ์œผ๋กœ ์˜จ๋„๊ฐ€ ๊ฐ์†Œํ•˜๊ฒŒ๋” ์œ ์ง€ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” monotonic stack ์œ ํ˜•


0199. Binary Tree Right Side View / 0031. Next Permutation

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
from collections import deque
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        ans = []
        queue = deque()
        queue.append(root)

        while queue:
            qLen = len(queue)
            level = []
            for i in range(qLen):
                node = queue.popleft()
                if node:
                    level.append(node.val)
                    queue.append(node.left)
                    queue.append(node.right)

            if level:       
                ans.append(level[-1])

        return ans
class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        l=len(nums)
        i=l-2
        
        #find the pivot
        while i>=0 and nums[i]>=nums[i+1]:
            i-=1

        if i>=0: #if pivot, swap
            j=l-1
            while nums[j]<=nums[i]: #find the rigthmost successor
                j-=1
            nums[i],nums[j] = nums[j],nums[i] #swap
            nums[i+1:] = reversed(nums[i+1:]) #reverse the suffix
            return nums
        else:
            #if no pivot
            #rearranged as the lowest possible order
            #(i.e., sorted in ascending order).
            nums = nums.sort()
            return nums

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0199) tree์˜ ๊ฐ level ๋ณ„ ๋งจ ์˜ค๋ฅธ์ชฝ node์˜ val์„ ๋ชจ์•„ ๋‘” ans update. BFS๋กœ root๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์ฐจ๋ก€๋Œ€๋กœ ๋‚ด๋ ค๊ฐ€๋ฉด์„œ queue์˜ ๊ฐœ์ˆ˜๊ฐ€ ๊ณง ํ˜„์žฌ์˜ level๋‚ด์˜ node ๊ฐœ์ˆ˜์ด๋ฏ€๋กœ(null ํฌํ•จ), popleft() ์ง„ํ–‰ ํ›„ if node์ผ ๋•Œ๋งŒ level์— ์‹ค์ œ value ๋„ฃ๊ธฐ. ํ•œ level์ด ๋ชจ๋‘ ๋๋‚˜๋ฉด level list์— ๋ฌด์–ธ๊ฐ€ ์กด์žฌํ•œ๋‹ค๋ฉด level[-1] appendํ•ด์„œ ๋ˆ„์  ๊ฒฐ๊ณผ ans ์ถœ๋ ฅ

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป0031) ์œ ๋ช…ํ•œ ์กฐํ•ฉ๋ก  <next permutation> ๋ฌธ์ œ. ๋ณ„๋„ ํฌ์ŠคํŒ… ์ฐธ์กฐ


0438. Find All Anagrams in a String / 0036. Valud Sudoku

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        from collections import Counter, defaultdict
        freq = dict(Counter(p))
        length = len(p)
        cur_freq = defaultdict(int)
        ans = []
        bf = 0
        for i in range(len(s)):
            cur_freq[s[i]] += 1
            if i == (length -1):
                if freq == cur_freq:
                    ans.append(i-len(p)+1)
            elif length <= i:
                cur_freq[s[bf]] -= 1
                if cur_freq[s[bf]] == 0:
                    del cur_freq[s[bf]]
                bf+=1
                if freq == cur_freq:
                    ans.append(i-len(p)+1)
        return ans
class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        import collections
        cols = collections.defaultdict(set)
        rows = collections.defaultdict(set)
        squares = collections.defaultdict(set)

        for r in range(9):
            for c in range(9):
                if board[r][c] == ".":
                    continue
                if (board[r][c] in rows[r] or board[r][c] in cols[c] or board[r][c] in squares[(r//3, c//3)]):
                    return False
                cols[c].add(board[r][c])
                rows[r].add(board[r][c])
                squares[(r//3, c//3)].add(board[r][c])
        return True

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0438) sliding window ๊ธฐ๋ฒ•์œผ๋กœ ํ˜„์žฌ index๋ถ€ํ„ฐ p length๊นŒ์ง€ cur_freq dict updateํ•˜๋‹ค๊ฐ€, p length index๋ถ€ํ„ฐ ๋งจ ์•ž ๋ฌธ์ž ๋นˆ๋„์ˆ˜ 1 ๊ฐ์†Œ ๋ฐ ๋งจ ์˜ค๋ฅธ์ชฝ ๋ฌธ์ž ๋นˆ๋„์ˆ˜ 1๋งŒ ์ฆ๊ฐ€์‹œํ‚ด์œผ๋กœ์จ O(N)์œผ๋กœ cur_freq dict updateํ•˜๋ฉฐ ์›๋ž˜ freq์™€ ๋น„๊ตํ•˜๋ฉฐ ๋งž์„ ๋•Œ index update.

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0036) ๊ฐ row์™€ col์— ๋“ค์–ด๊ฐˆ ์ˆซ์ž set๋กœ ๋งŒ๋“ค์–ด์„œ rows์™€ cols dictionary ๋งŒ๋“ค๊ธฐ. ์ถ”๊ฐ€๋กœ squares๋ผ๋Š” set๊ฐ€ ๋“ค์–ด๊ฐ„ dictionary ๋งŒ๋“ค์–ด์„œ squares๋„ update. squares๋Š” ํ˜„์žฌ (r,c)์—์„œ index ๊ธฐ์ค€ squares์˜ (r//3,c//3)์— ์ˆซ์ž๋ฅผ ๋„ฃ๋Š”๋‹ค.(9x9 ์ •์‚ฌ๊ฐํ˜• ๋‚ด์—์„œ 3x3 ์ •์‚ฌ๊ฐํ˜• ์˜์—ญ)


0113. Path Sum II / 0189. Rotate Array

 

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        ans = []
        def dfs(node, l):
            if not node.left and not node.right: #if this is a leaf node
                if sum(l) == targetSum:
                    ans.append(l[:])
            else: #if this is not a leaf node
                if node.left:
                    l.append(node.left.val)
                    dfs(node.left,l)
                    l.pop()
                if node.right:
                    l.append(node.right.val)
                    dfs(node.right,l)
                    l.pop()        
        if root:
            dfs(root, [root.val])
        return ans
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        k%=(len(nums))

        #reverse
        l,r = 0,len(nums)-1
        while l<=r:
            nums[l], nums[r] = nums[r], nums[l]
            l+=1
            r-=1
        
        #reverse first kth array
        l,r = 0,k-1
        while l<=r:
            nums[l], nums[r] = nums[r], nums[l]
            l+=1
            r-=1
        
        #reverse (k+1)th to the last-th array
        l,r = k,len(nums)-1
        while l<=r:
            nums[l], nums[r] = nums[r], nums[l]
            l+=1
            r-=1

        return nums

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0113) Easy Version 0112. Path Sum I๊ณผ ๋™์ผ ๋ฌธ์ œ. ๋‹ค๋งŒ, leaf node๊นŒ์ง€์˜ ๊ฒฝ๋กœ์˜ ํ•ฉ์ด ๋ชจ๋‘ targetSumํ•˜๊ณ  ๊ฐ™์„ ๋•Œ์˜ ๊ฒฝ๋กœ ๊ณ„์† ans์— update. ์ „ํ˜•์ ์ธ dfs backtracking ์ง„ํ–‰

 

* dfs(node, l) ์ง„ํ–‰

โ‘  return ์กฐ๊ฑด) ํ•ด๋‹น node๊ฐ€ leaf node๋ผ๋ฉด, ๋งŒ์•ฝ sum(l) == targetSum์ผ ๊ฒฝ์šฐ list l ๋‚ด์˜ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ans list์— ๊ทธ๋Œ€๋กœ update

 

โ‘ก leaf node๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ ํ•ด๋‹น node์˜ left node / right node์— ๊ฐ๊ฐ value๊ฐ€ ์žˆ๊ณ  ์—†์„ ๊ฒฝ์šฐ ํ™•์ธํ•ด dfs(node.left, l) / dfs(node.right, l) ๊ฐ๊ฐ ์ง„ํ–‰

: ๋™์ผ ํ•จ์ˆ˜ ์œ„ ๋‚ด์šฉ์—” l.append() / ์ดํ›„์—” l.pop()์œผ๋กœ ์•ž ๋’ค ์ƒํ™ฉ backtracking ์œ ํ˜•์— ๋งž๊ฒŒ ๊ตฌํ˜„ ์ง€ํ‚ค๊ธฐ ๊ผญ ๊ธฐ์–ต

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป0189) k๋ฒˆ ์ด๋™ํ•œ ๊ฒฐ๊ณผ์˜ array๋ฅผ in-place ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ•˜๋ ค๋ฉด, ๋จผ์ € reverse๋ฅผ ์ง„ํ–‰ํ•œ ๋’ค, index ๊ธฐ์ค€ 0 ~ k-1 / k ~๋๊นŒ์ง€์˜ ๊ฐ subarray๋ฅผ ๊ฐ๊ฐ reverse ์ง„ํ–‰ํ•œ๋‹ค. (in-place reverse์ด๋ฏ€๋กœ ์–‘ ๋์— ํˆฌ ํฌ์ธํ„ฐ๋ฅผ ๋‘์–ด์„œ ๋‘ ํฌ์ธํ„ฐ๊ฐ€ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ swap ์ง„ํ–‰)


0050. Pow(x,n) / 0560. Subarray Sum Equals K

class Solution:
    def myPow(self, x: float, n: int) -> float:
        def get_pow(x,n):
            if n==0:
                return 1
            halved = get_pow(x,n//2)
            if n%2 == 0:
                return  halved * halved
            else:
                return halved * halved * x
        res = get_pow(x, abs(n))
        return res if n >=0 else 1/res
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        res = 0
        curSum = 0
        prefixSums = { 0 : 1}
        for n in nums:
            curSum += n
            diff = curSum - k 
            res += prefixSums.get(diff,0)
            prefixSums[curSum] = 1 + prefixSums.get(curSum,0)
            print(prefixSums)
        
        return res

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0050) Power by Divide & Conquer ์œ ํ˜•.

โ‘  x^n์„ ๊ตฌํ•  ๋•Œ ๋งŒ์•ฝ, n์ด ์Œ์ˆ˜๋ผ๋ฉด x^(abs(n))์„ ๊ตฌํ•˜๊ณ , ๊ตฌํ•œ ๊ฒฐ๊ณผ๋ฅผ res๋ผ ํ•˜๋ฉด 1/res๋ฅผ ๊ตฌํ•˜๋ฉด ๋œ๋‹ค.

โ‘ก x^n = x^(n/2) * x^(n/2)๋กœ x^(n/2)๋ฅผ ๊ตฌํ•˜๋ฉด x^n์€ ๊ตฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณฑ๋งŒ ํ•˜๋ฉด ๋˜๋ฏ€๋กœ, O(logn) ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

โ‘ข n์„ 2๋กœ ๋‚˜๋ˆ„๊ณ  ๋‚˜๋ˆ„์–ด n์ด 0์ด ๋  ๋•Œ๊นŒ์ง€(์žฌ๊ท€์ด๋ฏ€๋กœ return ์กฐ๊ฑด n == 0์ผ ๋•Œ return 1) divide.

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0560) O(n)์„ ์ด์šฉํ•ด์„œ ๋ถ€๋ถ„ contiguous subarray์˜ ํ•ฉ์ด k๊ฐ€ ๋˜๋Š” ์Œ์˜ ๊ฐœ์ˆ˜ ๊ตฌํ•˜๊ธฐ. 

for๋ฌธ์œผ๋กœ O(n) ๋Œ๋ฆฌ๋ฉด์„œ, ํ˜„์žฌ ํ•ด๋‹น ์›์†Œ๋ฅผ ๋์œผ๋กœ ํ•˜๋Š” contiguous subarray ์ค‘ ํ•ฉ์ด k๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋ˆ„์ ์œผ๋กœ ๋”ํ•ด ๋‚˜๊ฐ€๋ฉด ๋œ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์›์†Œ 2์ผ ๋•Œ, ์›์†Œ 2๋ฅผ ๋์œผ๋กœ ํ•˜๋Š” contiguous subarray๋Š” {-3, -1, 4, 3, 1, 2}, {-1, 4, 3, 1, 2}, {4, 3, 1, 2}, {3, 1, 2}, {1, 2}, {2} ์ด๋ ‡๊ฒŒ ์žˆ๋‹ค. ์ด ๋•Œ ๊ฐ๊ฐ์˜ array ๊ฐ๊ฐ์˜ ํ•ฉ์ด k๊ฐ€ ๋˜๋Š” ์ง€ ํ™•์ธํ•˜๋ ค๋ฉด O(n^2) ์†Œ์š”. ์ด ๋•Œ ์•„๋ž˜ ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ ๋ฐœ์ƒ์„ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์•ž์„  ๋ˆ„์ ํ•ฉ์˜ ๊ฒฐ๊ณผ๋ฅผ hash map์œผ๋กœ ์ €์žฅํ•˜๋ฉฐ ์—…๋ฐ์ดํŠธ. ๊ถ๊ทน์ ์œผ๋กœ index 0 ๋ถ€ํ„ฐ ํ˜„์žฌ ์›์†Œ i๊นŒ์ง€์˜ ๋ˆ„์ ํ•ฉ - k์ธ diff๋งŒํผ ํ•ด๋‹น๋˜๋Š” frequency(hash map indexing ๊ฒฐ๊ณผ)๋ฅผ ๋ˆ„์ ์œผ๋กœ ๋”ํ•ด์ฃผ์–ด์•ผ ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด hash map์˜ ๋„์›€์œผ๋กœ O(n)๋งŒ์— ๋ชจ๋“  contiguous subarray์˜ ํ•ฉ์ด k๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

* ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ๋ถ€๋ถ„ contiguous subarray์˜ ํ•ฉ์€ ์™ผ์ชฝ ๋๋ถ€ํ„ฐ ํ˜„์žฌ๊นŒ์ง€์˜ contiguous subarray์˜ ํ•ฉ์— ์•ž์„  ์™ผ์ชฝ ๋๋ถ€ํ„ฐ ๊ตฌํ•˜๊ณ ์ž ํ•˜๋Š” subarray์˜ ์•ž ์›์†Œ๊นŒ์ง€์˜ ํ•ฉ์„ ๋บ€ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๋Š” ์•„์ด๋””์–ด๋ฅผ ์‚ฌ์šฉ

 


0525. Contiguous Array / 0424. Longest Repeating Character Replacement

class Solution:
    def findMaxLength(self, nums: List[int]) -> int:
        zero, one = 0,0
        res = 0

        diff_index = {} #diff(count[1] - count[0]) -> index

        for i, n in enumerate(nums):
            if n == 0:
                zero += 1
            else:
                one += 1
            if one - zero not in diff_index:
                diff_index[one - zero] = i
            
            if one == zero: #answer
                res = one + zero
            else:
                idx = diff_index[one - zero]
                res = max(res, i - idx)
        return res
class Solution:
    def characterReplacement(self, s: str, k: int) -> int:
        count = {}
        res = 0

        l = 0
        maxf = 0
        for r in range(len(s)):
            count[s[r]] = 1 + count.get(s[r], 0)
            maxf = max(maxf, count[s[r]])

            while (r - l + 1) - maxf > k:
                count[s[l]] -= 1
                l += 1
            
            res = max(res, r-l+1)
        return res

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0525) hash map์— ๊ฐ index i๋ณ„ one-zero์˜ ๊ฐ’์„ ์ €์žฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ด ๋•Œ, ์˜ˆ๋ฅผ ๋“ค์–ด O(n)์œผ๋กœ for๋ฌธ์„ ๋Œ๋ฆฌ๋‹ค๊ฐ€ index i์— one - zero๊ฐ€ 3์ด๋ผ๋ฉด, index i ๋ณด๋‹ค ์•ž์˜ index j๊ฐ€ ๋™์ผํ•˜๊ฒŒ one - zero๊ฐ€ 3์ด๋ผ๊ณ  ํ•˜์ž. ๊ทธ๋Ÿฌ๋ฉด (i-j) ๋งŒํผ์˜ ์›์†Œ ๊ฐœ์ˆ˜, ์ฆ‰ index i+1๋ถ€ํ„ฐ j๊นŒ์ง€์˜ subarray์˜ one ๊ฐœ์ˆ˜ = zero ๊ฐœ์ˆ˜๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์„ ์ฐธ๊ณ ํ•˜์ž.

: ๋งจ ์˜ค๋ฅธ์ชฝ ์›์†Œ 1์„ ์˜ค๋ฅธ์ชฝ ๋์œผ๋กœ ๊ฐ–๊ณ  ์žˆ๋Š” subarray ์ค‘ ๋™๋“ฑํ•˜๊ฒŒ 0๊ณผ 1์„ ๊ฐ™์€ ๊ฐœ์ˆ˜๋กœ ๊ฐ–๊ณ  ์žˆ๋Š” ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด, one-zero๊ฐ€ 2์ธ ๋™์ผ ์œ„์น˜๋Š” ๋‘๊ตฐ๋ฐ. O(n)์œผ๋กœ iteration ์ง„ํ–‰ํ•  ์ˆ˜๋ก ๊ธฐ์กด diff๊ฐ’์ด diff_index key๊ฐ’์— ์กด์žฌํ•˜๋ฉด ํŒจ์Šค. ์—†์„ ๋•Œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์Œ์œผ๋กœ์จ ๊ฐ€์žฅ ๊ธด ๊ธธ์ด์˜ one-zero๊ฐ’์˜ ๊ธธ์ด๋ฅผ ๋ณด์กดํ•œ๋‹ค.

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0424) ์ƒ๋‹นํžˆ ์–ด๋ ค์šด ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๋ฌธ์ œ. for๋ฌธ์œผ๋กœ O(n)๋งŒํผ ๋Œ๋ฆฌ๋ฉฐ freq count dictionary ์—…๋ฐ์ดํŠธ. O(n)๋งŒํผ ๋Œ๋ฆฌ๋ฉฐ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง€๋Š”๋ฐ, ์ด ๋•Œ (์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ ๊ธธ์ด - ์—…๋ฐ์ดํŠธ ๋˜๋Š” max_frequency(maxf))๊ฐ€ k๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ•ด๋‹น ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ ๊ธธ์ด์— ๋™์ผ character๋งŒ ๋ชจ๋‘ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป. ํ•˜์ง€๋งŒ, ๊ทธ ๋ฐ˜๋Œ€๋กœ k๋ณด๋‹ค ํฌ๋‹ค๋ฉด ํ•ด๋‹น ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๊ธธ์ด์— ๋™์ผ character๋ฅผ ๋ชจ๋‘ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ, ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ l ์™ผ์ชฝ ํฌ์ธํ„ฐ๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋ฉด์„œ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๊ธธ์ด๋ฅผ ์ค„์ด๋ฉฐ ์—…๋ฐ์ดํŠธ. l๊ณผ r ์™ผ์ชฝ ์˜ค๋ฅธ์ชฝ ํฌ์ธํ„ฐ๋กœ ์ด๋ฃจ์–ด์ง„ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ: r์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์›€์ง์ด๋ฉด์„œ ์ตœ๋Œ€ํ•œ res ์ •๋‹ต ์ตœ๋Œ“๊ฐ’์„ ์ฐพ๊ณ , ๋” ์ด์ƒ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋ฉด l์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์›€์ง์ด๋ฉด์„œ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ ๊ธธ์ด ์กฐ์ ˆ.

 


0007. Reverse Integer / 0074. Search a 2D Matrix

class Solution:
    def reverse(self, x: int) -> int:
        if x>0:
            value=int(str(x)[::-1]) #reversed
        else: 
            value=-1*int(str(x*-1)[::-1])  #reversed
        
        if value not in range(-2**31,2**31): #Overflow 
            value=0
            
        return value
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        row, col = len(matrix), len(matrix[0])
        target_in_a_row = -1
        for x in range(row):
            if target < matrix[x][0]:
                break
            target_in_a_row = x
        if target_in_a_row == -1:
            return False
        l = matrix[target_in_a_row]
        
        start, end = 0, len(l)-1
        while start<=end:
            mid = (start+end)//2
            if target == l[mid]:
                return True
            elif target < l[mid]:
                end = mid - 1
            else:
                start = mid + 1
        return False

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0007) ์‰ฝ๊ฒŒ [::-1]๋กœ reverse slicing

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0074) ๋จผ์ € target์ด ๋ช‡๋ฒˆ์งธ ํ–‰์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ์ง€ ํ™•์ธ(๋ช‡๋ฒˆ์งธ ํ–‰์ธ์ง€ ํฌํ•จ ๋ชจ๋ฅด๋ฉด False ๋ฆฌํ„ด) / ๊ทธ ๋‹ค์Œ, ํฌํ•จ๋œ ํ–‰์„ ์ด๋ถ„ ํƒ์ƒ‰์œผ๋กœ ๋Œ๋ ค target์˜ ์—ฌ๋ถ€ ํ™•์ธ. ์ด๋ฏธ ์ •๋ ฌ๋œ ํ–‰์ด๋ฏ€๋กœ ์ •๋ ฌ ์—†์ด ๋ฐ”๋กœ ์ง„ํ–‰. 


0179. Largest Number / 0016. 3Sum Closest

class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        nums = list(map(str, nums))
        nums.sort(key=lambda x: x*10, reverse=True)
        return str(int(''.join(nums)))
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        res = nums[0] + nums[1] + nums[2]
                
        for i in range(len(nums)-2):
            l, r = i+1, len(nums)-1
            while l < r:
                s = nums[i] + nums[l] + nums[r]
                if s == target:
                    return s
                if abs(s - target) < abs(res - target):
                    res = s
                if s < target:
                    l += 1
                else:
                    r -= 1
                            
        return res

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0179) ์ฃผ์–ด์ง„ ๋ฆฌ์ŠคํŠธ ๋‚ด์˜ ์—ฌ๋Ÿฌ ์ˆซ์ž๋ฅผ 10๋ฒˆ ๋ฐ˜๋ณตํ•ด์„œ ์‚ฌ์ „์ˆœ ์ •๋ ฌ. ์ฆ‰ ๋งจ ์•ž์˜ ์ˆซ์ž๋ฅผ ๋น„๊ตํ•ด ํ™•์ธ. ์˜ˆ๋ฅผ ๋“ค์–ด 3๊ณผ 34๋ฅผ ๋น„๊ตํ•œ๋‹ค๋ฉด 334์™€ 343์ด ๋˜๋Š”๋ฐ 34๊ฐ€ ๋จผ์ € ์˜ค๊ณ  3์ด ๊ทธ ๋‹ค์Œ ์˜ค๋Š” ๊ฒŒ ๋งž๋‹ค. ์ด๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” 3์„ 10๋ฒˆ ๋ฐ˜๋ณตํ•œ ๊ฒฐ๊ณผ / 34๋ฅผ 10๋ฒˆ ๋ฐ˜๋ณตํ•œ ๊ฒฐ๊ณผ ์ค‘ ์‚ฌ์ „ ์ˆœ ์•ž์„œ๋Š” ๊ฑธ ํ™•์ธ. 3์„ 10๋ฒˆ ๋ฐ˜๋ณตํ•œ๊ฒŒ ์‚ฌ์ „ ์ˆœ ์•ž์„œ๋ฏ€๋กœ ์‚ฌ์ „ ์ˆœ ๋’ค(reverse=True)์˜ ๋ฌธ์ž์—ด์„ ๋จผ์ € ์˜ค๊ฒŒ ํ•œ๋‹ค. ์ฆ‰ ๋™์ผ ๋ฌธ์ž์—ด์„ 10๋ฒˆ ๋ฐ˜๋ณตํ•˜๊ฒŒ ํ•ด์„œ ์ •๋ ฌ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0016) i ๊ณ ์ •ํ•˜๊ณ , j์™€ k ํˆฌ ํฌ์ธํ„ฐ๋ฅผ i+1๋ถ€ํ„ฐ len(nums)-1๊นŒ์ง€ ๋Œ๋ฆฌ๋ฉด ๋œ๋‹ค. ํ•œ ๊ฐœ ํฌ์ธํ„ฐ ๊ณ ์ •ํ•˜๊ณ  ์ญ‰ ๋‚˜๋จธ์ง€ ๋Œ๋ฆฌ๋Š” ํˆฌ ํฌ์ธํ„ฐ ๋ฐฉ์‹ ๋™์ผ.


0227. Basic Calculator II / 0019. Remove Nth Node From End of List

class Solution:
    def calculate(self, s: str) -> int:
        stack = []
        mul, share = False, False
        ans = 0
        real_s = []
        for character in s:
            if character != ' ':
                if not real_s:
                    real_s.append(character)
                else:
                    if character in ['-','+','*','/']:
                        real_s.append(character)
                    else:
                        if real_s[-1] in ['-','+','*','/']:
                            real_s.append(character)
                        else:
                            real_s.append(real_s.pop()+character)
        for character in real_s:
            if character.isdigit():
                if mul:
                    stack.append(int(stack.pop())*int(character))
                    mul = False
                elif share:
                    stack.append(int(stack.pop())//int(character))
                    share = False
                else:
                    stack.append(character)
            else:
                if character == '*':
                    mul = True
                elif character == '/':
                    share = True
                else:
                    stack.append(character)
        while stack:
            popped = stack.pop()
            if str(popped).isdigit():
                popped = int(popped)
                tmp = popped
            else:
                if popped == '-':
                    ans += (-tmp)
                else:
                    ans += tmp
        ans+=int(popped)
        return ans
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        #get length
        node = head
        length = 1
        while node.next != None:
            node = node.next
            length+=1

        #remove order-th node
        order = length - n
        node = head
        before = None
        order_i = 0

        while node != None:
            if order_i == order:
                if before == None:
                    head = node.next
                else:
                    before.next = node.next
                break
            before = node
            node = node.next
            order_i+=1
            
        return head

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0227)

โ‘  '33 /   319 +2-1'๊ณผ ๊ฐ™์€ exp๊ฐ€ ์žˆ๋‹ค๋ฉด ๋„์–ด์“ฐ๊ธฐ ๋ชจ๋‘ ์ƒ๋žตํ•˜๊ณ , ์ˆซ์ž๋Š” ์ˆซ์ž๋ผ๋ฆฌ ๋จผ์ € ๋ถ™์—ฌ์„œ real_s ๋งŒ๋“ค๊ธฐ

โ‘ก ์ผ๋‹จ *์™€ /๋งŒ ๋จผ์ € ์ง„ํ–‰๋˜๋ฏ€๋กœ +์™€ -๋Š” ๊ทธ๋Œ€๋กœ ๋„ฃ๊ณ , *์™€ /์ธ ๊ฒฝ์šฐ๋งŒ ์—ฐ์‚ฐํ•ด์„œ ๋จผ์ € stack ์™„์„ฑ

ex) '33*2+3'์ด ์žˆ๋‹ค๋ฉด '66+3'์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

โ‘ข '3+1-2'์™€ ๊ฐ™์ด +์™€ -๋งŒ ๊ตฌ์„ฑ๋œ stack์—์„œ ๊ฑฐ๊พธ๋กœ ์•ž์— ๋ถ€ํ˜ธ๊ฐ€ +๋ผ๋ฉด popped๋ฅผ ๊ทธ์ € ๋”ํ•˜๊ณ , -๋ผ๋ฉด -popped๋ฅผ ๋”ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งจ ์•ž์— ๋‚จ์€ ์ˆซ์ž๋Š” while stack ์ข…๋ฃŒ ์ดํ›„ ans += int(popped) ์—ฐ์‚ฐ์œผ๋กœ ans update → return ans

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0019)

โ‘  ๋จผ์ € head ์ฒซ๋ฒˆ์งธ ๋…ธ๋“œ node๋ถ€ํ„ฐ node.next != None์ผ ๋•Œ๊นŒ์ง€ ํ•œ ๋ฐ”ํ€ด ๊ณ„์† ๋Œ๋ฆฌ๋ฉด์„œ node = node.next๋กœ ์—…๋ฐ์ดํŠธํ•˜๋ฉฐ(์ฆ‰, linked list๋ฅผ ๋Œ๋ฆฌ๋ฉฐ) length += 1๋กœ linked list์˜ ์ „์ฒด ๊ธธ์ด length ๊ตฌํ•˜๊ธฐ

โ‘ก ๊ทธ๋Ÿฌ๋ฉด order(length - n)๋ฒˆ์งธ์˜ node๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ. order_i = 0์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์ •ํ•ด order_i == order์ผ ๋•Œ ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์•ž๊ณผ ๋’ค์˜ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์•„์ด๋””์–ด๋ฅผ ์ƒ๊ฐํ•ด์•ผ ํ•œ๋‹ค. ํ˜„์žฌ node์˜ ์•ž์˜ node๋ฅผ before๋ผ๊ณ  ํ•˜๋ฉด, ์•ž์˜ ๋…ธ๋“œ๊ฐ€ ํ˜„์žฌ node์˜ ๋’ค์˜ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐํ•˜๊ฒŒ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

(1) before node๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ: ์•„๋ž˜์™€ ๊ฐ™์ด before.next =node.next

(2) before node๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ(์ฆ‰, ํ˜„์žฌ node๊ฐ€ ๋งจ ์•ž์˜ node์ผ ๊ฒฝ์šฐ): ์•„๋ž˜์™€ ๊ฐ™์ด node.next๊ฐ€ ๋งจ ์•ž์˜ head๊ฐ€ ๋˜๋ฏ€๋กœ head = node.next

โ‘ข ๊ณ„์† while๋ฌธ์„ ๋Œ๋ฆฌ๋ฉด์„œ before, node, order_i๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ before = node / node = node.next / order_i += 1 ์ฝ”๋“œ


0328. Odd Even Linked List / (โ˜…) 0024. Swap Nodes in Pairs

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        order = 0
        odd_head = None
        odd_before = None
        even_head = None
        even_before = None
        cur_node = head
        
        while cur_node != None:
            if order == 0:
                even_head = cur_node
                even_before = cur_node
            elif order == 1:
                odd_head = cur_node
                odd_before = cur_node
            else:
                if order%2==1:
                    odd_before.next = cur_node
                    odd_before = cur_node
                else:
                    even_before.next = cur_node
                    even_before = cur_node

            order+=1
            cur_node = cur_node.next
            if even_before:
                even_before.next = None
            if odd_before:
                odd_before.next = None
        
        cur_node = even_head
        if cur_node:
            while cur_node.next != None:
                cur_node = cur_node.next
            cur_node.next = odd_head
        return even_head
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode(0, head)
        prev, curr = dummy, head

        while curr and curr.next: #need at least two nodes
            #save ptrs
            nxtPair = curr.next.next
            second = curr.next

            #reverse this pair
            second.next = curr
            curr.next = nxtPair
            prev.next = second

            #update ptrs
            prev = curr
            curr = nxtPair
        
        return dummy.next

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0328)

** Space Complexity O(1)๋กœ ์‰ฝ๊ฒŒ odd number nodes์™€ even number nodes ๊ฐ๊ฐ ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.

โ‘  odd์šฉ linked list์™€ even์šฉ linked list๋ฅผ ๊ธฐ์กด linked list์—์„œ ๊ฐ๊ฐ ์ชผ๊ฐœ๊ธฐ ์•„์ด๋””์–ด.

โ‘ก ์ฒซ๋ฒˆ์งธ์™€ ๋‘๋ฒˆ์งธ node ๋„๋‹ฌ ์‹œ even_before, even_head / odd_before, odd_head ๊ฐ๊ฐ ์ดˆ๊ธฐํ™”

โ‘ข ์„ธ๋ฒˆ์งธ ์ด์ƒ์˜ node ๋„๋‹ฌ ์‹œ even node๋ผ๋ฉด even_before.next = cur_node๋กœ ์—ฐ๊ฒฐ. ๊ทธ๋ฆฌ๊ณ  even_before๋ฅผ cur_node๋กœ update / odd node๋„ ๋งˆ์ฐฌ๊ฐ€์ง€

โ‘ฃ (**์ฃผ์˜) cur_node update ํ›„ ์—…๋ฐ์ดํŠธ ๋˜๋Š” even_before / odd_before์˜ next ๊ฐ’์„ None์œผ๋กœ ๋ฐ”๊พธ์–ด ์ง์ˆ˜ node์˜ ๊ฒฝ์šฐ node 4 -> node 5๊ฐ€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๋„๋ก ๋‘ ์ข…๋ฅ˜์˜ before๋ฅผ ์ง€์†์ ์œผ๋กœ update

โ‘ค odd_head์™€ even_head ๋‘ ์ข…๋ฅ˜์˜ linked list ๋งŒ๋“ค์–ด์กŒ๋‹ค๋ฉด, even_head linked list๋ฅผ while๋ฌธ์œผ๋กœ ๋Œ๋ ค even_head linked list ๋งจ ์˜ค๋ฅธ์ชฝ node๋กœ cur_node pointer ์˜ฎ๊ธฐ๊ธฐ. ๊ทธ๋ฆฌ๊ณ  ์˜ฎ๊ฒจ์ง„ ์ตœ์ข… cur_node์˜ next๋ฅผ odd_head๋กœ ์„ค์ •ํ•ด ๋‘ linked list ์—ฐ๊ฒฐํ•˜๋ฉด ๋!

 

๐Ÿง‘๐Ÿป‍๐Ÿ’ป 0024) pair ๊ธฐ์ค€ reverse ๋ฌธ์ œ์ด๋ฏ€๋กœ ๋‘ ์นธ ์”ฉ ์›€์ง์ด๋ฉฐ swapํ•˜๋ฉด ๋˜๋Š” idea๋ฅผ ์ƒ๊ฐํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ.

โ‘  ํ˜„์žฌ curr ๊ธฐ์ค€ ๋ฐ”๋กœ ์•ž node๋ฅผ prev, ๋ฐ”๋กœ ๋’ค node๋ฅผ second, ๋’ค์˜ ๋’ค์˜ node๋ฅผ nxtPair๋ผ ํ•˜์ž(while curr and curr.next๋ผ ํ•˜์˜€์œผ๋ฏ€๋กœ pair๋กœ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋งŒ while๋ฌธ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค)

โ‘ก prev -> second / second -> curr / curr -> nxtPair ์ด๋ ‡๊ฒŒ ์„ธ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ๊ฐ ๋‹ค๋ฅธ node๋กœ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋ฐฉํ–ฅ์„ ์—…๋ฐ์ดํŠธ

โ‘ข prev, curr update

* ๋งจ ์•ž์— dummy ptr ์•„์ด๋””์–ด๋ฅผ ์ƒ๊ฐํ•ด ๋‚ด ์ด 3๊ฐœ์˜ ์—ฐ๊ฒฐ ์ค„์„ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด๊ฐ€ ์ค‘์š”


๋Œ“๊ธ€