algorithm/problem solving
leetcode 509, 1137(피보나치), 746(계단, dp), 698(dfs)
qkqhxla1
2021. 2. 7. 23:08
509 leetcode.com/problems/fibonacci-number/
알고리즘 공부 시작하는 처음에 가장 먼저 배우는 쉬운거
class Solution(object): def fib(self, n): if n == 0: return 0 f = [0] * (n+1) f[1] = 1 for i in xrange(2, n + 1): f[i] = f[i-1] + f[i-2] return f[n]
복습용으로 읽어보는게 더 좋다 : leetcode.com/problems/fibonacci-number/discuss/215992/Java-Solutions
1137 leetcode.com/problems/n-th-tribonacci-number/
위랑 똑같음.
class Solution(object): def tribonacci(self, n): #n = 2 if n == 0: return 0 elif n == 1: return 1 f = [0] * (n+1) f[1] = 1 f[2] = 1 for i in xrange(3, n + 1): f[i] = f[i-1] + f[i-2] + f[i-3] return f[n]
746 leetcode.com/problems/min-cost-climbing-stairs/
기초적인 dp문제 2. 백준의 www.acmicpc.net/problem/2579 와 비슷하다.
class Solution(object): def minCostClimbingStairs(self, cost): #cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] n = len(cost) if n == 1: return cost[0] dp = [0] * n dp[0] = cost[0] dp[1] = cost[1] for i in xrange(2, n): dp[i] = cost[i] + min(dp[i-2], dp[i-1]) return min(dp[n-1], dp[n-2])
698 leetcode.com/problems/partition-to-k-equal-sum-subsets/
dfs문제이다. n개의 리스트를 합이 동일한 k개의 리스트로 나눌수 있는지 물어보는 문제인데
1. 리스트 전체합 / k가 나머지없이 나누어 떨어지면 가능한거니 안 나누어 떨어지는 경우 제외
2. 모든 경우의 수 dfs탐색.
처음에 iterative하게 짰었는데 방문한 곳을 표시하는 visited를 매번 복사해서 집어넣어야 하다 보니 시간초과가 걸려서 재귀적으로 짰다.
class Solution(object): def canPartitionKSubsets(self, nums, k): # nums = [1,1, 1,1, 1,1, 1,1, 1,1] # k = 5 # nums = [10, 10, 10, 7, 7, 7, 7, 7, 7, 6, 6, 6] # k = 3 #nums = [780, 935, 2439, 444, 513, 1603, 504, 2162, 432, 110, 1856, 575, 172, 367, 288, 316] #k = 4 num_sum = sum(nums) if num_sum % k != 0: return False target_subsum = num_sum / k visited = {} def DFS(k, index, cur_sum): if k == 0: return True if cur_sum == target_subsum: return DFS(k-1, 0, 0) for i in xrange(index, len(nums)): if not visited.get(i, False) and cur_sum + nums[i] <= target_subsum: visited[i] = True if DFS(k, i+1, cur_sum+nums[i]): return True visited[i] = False return False return DFS(k, 0, 0)