代码
func climbStairs(n int) int {
if n==1 {
return 1
} else if n==2 {
return 2
}
ans1, ans2 := 1,2
tmp := 0
n-=2
for n>0 {
tmp = ans2
ans2+=ans1
ans1=tmp
n--
}
return ans2
}
思路
- 想法
- 这道题本质上还是斐波那契数列,是动态规划,思考方式同样是分治法。
- 可以从1列到4或者5,可以发现
- 解法
- 如何上第n节台阶,可以通过n-2节台阶走两步,或者通过n-1节台阶走一步。
- F(n)=F(n-1)+F(n-2)
- 做法
- ans1来储存n-2台阶的方法数,ans2来存储n-1台阶的方法数
性能
代码
func maxSubArray(nums []int) int {
ans := nums[0]
tmp := nums[0]
n := len(nums)
i := 1
for ; i<n; i++ {
tmp = max(tmp+nums[i], nums[i])
ans = max(ans, tmp)
}
return ans
}
func max (i, j int) int {
if i>j {
return i
}
return j
}
思路
- 可以知道是道动态规划,重要的有两点:1.定义状态,定义子问题。2.状态转移方程
- 1.定义子问题
- 2.状态转移方程
- 选择
dp[i-1]+nums[i]<nums[i]和nums[i]大的那个
- 3.事例
[-2,1,-3,4,-1,2,1,-5,4]
- 第一个,一定是-2
- 第二个,选择-2+1或者1,一定是1
- 第三个,选择1+(-3)或者-3,选择-2
- 第四个,选择-2或者4,一定是4
- 第五个,选择3或者-1,一定是3
- 第六个,选择5或者2,一定是5
性能
代码
func coinChange(coins []int, amount int) int {
ans := make([]int, amount+1)
n:=len(coins)
i := 1
j := 0
min := 10001
for i<=amount {
ans[i]=-1
min = 10001
for j=0; j<n; j++ {
if i-coins[j]>=0 && ans[i-coins[j]]!=-1 {
min = theMin(min, ans[i-coins[j]]+1)
}
}
if min != 10001 {
ans[i]=min
}
i++
}
return ans[amount]
}
func theMin(i, j int) int {
if i<j {
return i
}
return j
}
思路
- 动态规划两个核心问题:1.子问题定义,2.状态转移方程
- 子问题定义:
- 状态转移方程:
F(i)=Min(F(i-conis[0])+1, F(i-conis[1]+1, ......)
- 简短解释:比
i-conis[j]元最少的钱数+1。
- 标准解释:
- i是期望的钱数,j是每一个可以用的硬币
- 如果
i-conis[j]能被满足,那它的结果+1,就可以构造i元钱,就可能是构建i最少硬币数。
- 贪心不能解决的测试case:
性能
代码
思路
性能
代码
func minPathSum(grid [][]int) int {
n := len(grid)
m := len(grid[0])
i:=0
j:=0
for i=1; i<n; i++ {
grid[i][0]+=grid[i-1][0]
}
for i=1; i<m; i++ {
grid[0][i]+=grid[0][i-1]
}
for i=1; i<n; i++ {
for j=1; j<m; j++ {
grid[i][j]+=min(grid[i-1][j], grid[i][j-1])
}
}
return grid[n-1][m-1]
}
func min(i, j int) int {
if i<j {
return i
}
return j
}
思路
- 到达每一位的最小值
- 是上边的或左边的最小的,
- 加自己。
- 总结:
grid[i][j]+=min(grid[i-1][j], grid[i][j-1])
性能
- 时间复杂度:
O(n*n)
- 空间复杂度:O(1),直接修改原数组,额外只需要常数空间
代码
思路
性能
代码
func maxProfit(prices []int) int {
theMin := prices[0]
ans := 0
for _, v := range prices {
ans = max(ans, v-theMin)
theMin = min(theMin, v)
}
return ans
}
func min(i, j int) int {
if i<j {
return i
}
return j
}
func max(i, j int) int {
if i>j {
return i
}
return j
}
思路
- 当前最多挣的钱数 = 之前最大的 - 之前最小的,(之前最小的要在之前最大的之前)
- 记录之前最多挣的钱数:ans,
- 记录之前最小的那个值。
- ans = max(ans, 当前的值-之前最小的值)
性能
代码
思路
性能
代码
思路
性能