diff --git a/Dynamic Program/Kilien/121.best-time-to-buy-and-sell-stock.py b/Dynamic Program/Kilien/121.best-time-to-buy-and-sell-stock.py new file mode 100644 index 0000000000000000000000000000000000000000..90ddc22b9c3aa9c4480f66f50d789d27c33cb658 --- /dev/null +++ b/Dynamic Program/Kilien/121.best-time-to-buy-and-sell-stock.py @@ -0,0 +1,37 @@ +# @Author:Kilien +# @lc app=leetcode id=121 lang=python3 +# [121] Best Time to Buy and Sell Stock +# 思路:DP[i][j],两个维度,i = 天数,j = 是否持有股票;当j=0,只能买股票,j=1,可以卖股票 +# maxProfit[i, 0] = max(maxProfit[i-1][0], maxProfit[i-1][1] + prices[i]) +# maxProfit[i, 1] = max(maxProfit[i-1][1], maxProfit[i-1][0] - prices[i]) +class Solution: + def maxProfit(self, prices: List[int]) -> int: + if not prices: return 0 + + res = 0 + #三种状态: + #profit[0][0] 未持有股票 + #profit[0][1] 买入股票 + #profit[0][2] 卖出股票 + profit = [[0 for i in range(3)] for i in range(len(prices))] + profit[0][0], profit[0][1], profit[0][2] = 0, -prices[0], 0 + + for i in range(1, len(prices)): + profit[i][0] = profit[i-1][0] + profit[i][1] = max(profit[i-1][1], profit[i-1][0] - prices[i]) + profit[i][2] = profit[i-1][1] + prices[i] + res = max(res, profit[i][0], profit[i][1], profit[i][2]) + return res +''' +# 思路:由于只能买卖一次股票,可以遍历一次股票,将最近的股票交易利润记录下来,找出最大利润 +# maxCur = current maximum value +# maxSoFar = maximum value found so far + + def maxProfit(self, prices: List[int]) -> int: + maxCur, maxSoFar = 0, 0 + for i in range(1, len(prices)): + maxCur += prices[i] - prices[i-1] + maxCur = max(0, maxCur) + maxSoFar = max(maxCur, maxSoFar) + return maxSoFar +''' diff --git a/Dynamic Program/Kilien/122.best-time-to-buy-and-sell-stock-ii.py b/Dynamic Program/Kilien/122.best-time-to-buy-and-sell-stock-ii.py new file mode 100644 index 0000000000000000000000000000000000000000..0f3d1ea3aa71d3ad9d077e6accd7e1d9e0098ecc --- /dev/null +++ b/Dynamic Program/Kilien/122.best-time-to-buy-and-sell-stock-ii.py @@ -0,0 +1,25 @@ +# @Author:Kilien +# @lc app=leetcode id=122 lang=python3 +# +# [122] Best Time to Buy and Sell Stock II +# +# https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/ +# 思路:两个状态:是否持有股票; +# 状态转换: +# hold -> do nothing -> hold +# hold -> sell -> not hold +# not hold -> do nothing -> not hold +# not hold -> buy -> hold +class Solution: + def maxProfit(self, prices: List[int]) -> int: + hold = float('-inf')#负无穷大 + notHold = 0 + for i in prices: + hold = max(hold, notHold - i) + notHold = max(notHold, hold + i) + return max(hold, notHold) +''' +# 思路:明天的股价高于今天,即今天买入,明天卖出;反之,不交易 + def maxProfit(self, prices: List[int]) -> int: + return sum(max(prices[i + 1] - prices[i], 0) for i in range(len(prices) - 1)) +''' diff --git a/Dynamic Program/Kilien/322.coin-change.py b/Dynamic Program/Kilien/322.coin-change.py new file mode 100644 index 0000000000000000000000000000000000000000..ed58add0d83f4e4d251e7d1e3e3422601e8c311d --- /dev/null +++ b/Dynamic Program/Kilien/322.coin-change.py @@ -0,0 +1,36 @@ +# @Author:Kilien +# @lc app=leetcode id=322 lang=python3 +# +# [322] Coin Change +# +# https://leetcode.com/problems/coin-change/description/ + +''' + dp[i]是组成目标金额所需的最少的硬币数量,coin指代不同面值的硬币; + dp[amount] * (amount + 1) 初始化数组;dp[0]作为哨兵节点,初始状态 + 两层循环,先遍历金额,后遍历硬币面值;将最小组合动态置入dp状态数组 + dp方程:dp[i] = min(dp[i - coin]) + 1 +''' +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + dp = [amount] * (amount + 1) + dp[0] = 0 + for i in range(1, amount + 1): + for c in coins: + if i >= c: + dp[i] = min(dp[i], dp[i - c] + 1) + + if dp[amount] == amount + 1: + return -1 + return dp[amount] + +'''’ + def coinChange(self, coins: List[int], amount: int) -> int: + if amount == 0:return 0 + Max = float('inf') + dp = [0] + [Max] * amount + + for i in range(1, amount + 1): + dp[i] = min([dp[i - c] if i - c >= 0 else Max for c in coins]) + 1 + return [dp[amount], -1][dp[amount] == Max] +''' diff --git a/Recursion/Kilien/46.permutations.py b/Recursion/Kilien/46.permutations.py new file mode 100644 index 0000000000000000000000000000000000000000..26f7e4a4651391dbd5bd821fe8647a635bec7137 --- /dev/null +++ b/Recursion/Kilien/46.permutations.py @@ -0,0 +1,40 @@ +# @Author:Kilien +# @lc app=leetcode id=46 lang=python3 +# +# [46] Permutations +# +class Solution: +''' + 构造递归函数: + 终止条件:当 start == end 则将该组合放入list + 遍历 nums 数组,顺序置换两位数字位置; + start + 1,递归 + 还原置换的数字位置 +''' + def permute(self, nums: List[int]) -> List[List[int]]: + def backtrack(start, end): + if start == end: + ans.append(nums[:]) + for i in range(start, end): + nums[start], nums[i] = nums[i], nums[start] + backtrack(start+1, end) + nums[start], nums[i] = nums[i], nums[start] + + ans = [] + backtrack(0, len(nums)) + return ans + +''' +# DFS + def permute(self, nums: List[int]) -> List[List[int]]: + res = [] + self.dfs(nums, [], res) + return res + + def dfs(self, nums, path, res): + if not nums: + res.append(path) + return # backtracking + for i in range(len(nums)): + self.dfs(nums[:i]+nums[i+1:], path+[nums[i]], res) +''' diff --git a/Recursion/Kilien/69.sqrt-x.py b/Recursion/Kilien/69.sqrt-x.py new file mode 100644 index 0000000000000000000000000000000000000000..a033d6c11191f180085c084966134b5785ec8798 --- /dev/null +++ b/Recursion/Kilien/69.sqrt-x.py @@ -0,0 +1,30 @@ +# Author:Kilien +# @lc app=leetcode id=69 lang=python3 +# +# [69] Sqrt(x) +# +class Solution: +# 牛顿整除法 + def mySqrt(self, x: int) -> int: + r = x + 1 + while r*r > x: + r = int(r - (r*r -x)/(2*r)) + return r + +''' +# 强制转换。。 + def mySqrt(self, x: int) -> int: + return int(x**0.5) + +# 思路:二分查找 + def mySqrt(self, x: int) -> int: + l, r = 0, x + while l <= r: + mid = l + (r-l)//2 + if mid * mid <= x < (mid+1)*(mid+1): + return mid + elif x < mid * mid: + r = mid + else: + l = mid + 1 +'''