跳跃游戏
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
Example:
Input: [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Code(By myself):
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
if nums[0] >= len(nums) - 1:
return True
elif nums[0] == 0:
return False
if 0 not in nums:
return True
else:
for i in range(nums[0]+1):
if nums[0] < nums[i]+i:
if self.canJump(nums[i:]):
return True
return False
Code(others):
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
n=len(nums)
max_index=n-1
for i in range(n-2,-1,-1):
if i+nums[i]>=max_index:
max_index=i
return max_index==0
总结:
从后往前遍历,若能到达之后的点就前移
不同路径
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
How many possible unique paths are there?
Above is a 7 x 3 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
Example:
Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Right -> Down 2. Right -> Down -> Right 3. Down -> Right -> Right
Code(By myself):
class Solution(object):
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
# if n == 0 or m == 0:
# return
# if n == 1 or m == 1:
# return 1
# if m == 2 and n == 2:
# return 2
# if m == 3 and n == 2:
# return 3
# if m == 2 and n == 3:
# return 3
# else:
# return self.uniquePaths(m-1,n) + self.uniquePaths(m,n-1)
matrix = [[0 for i in range(n)] for j in range(m)]
for i in range(m):
for j in range(n):
if i == 0 or j == 0:
matrix[i][j] = 1
else:
matrix[i][j] = matrix[i-1][j] + matrix[i][j-1]
return matrix[m-1][n-1]
最先尝试用递归的方法进行求解,到达某点的步数为到达上方和左方步数之和,到达边界返回1,不过由于递归每次都重新探索,所以时间复杂度是结果数量的量级,而不是多项式的复杂度,因此时间超过了。
于是由于递推式已经得出,于是用一个m*n矩阵进行存储相应步数,时间复杂度为O(m*n)。空间复杂度为O(m*n)。该方法可以进一步优化用一个长度为min(m,n)的数组进行存储上一行/列的相应步数,递推式为res[i]+=res[i-1]不断重复更新,空间复杂度优化为O(min(m,n))。
Code(others):
class Solution(object):
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
j=min(m-1,n-1)
if j==0:
return 1
k=m+n-2
res1=1
res2=1
for i in range(j):
res1*=k-i
res2*=j-i
return res1/res2
该动态规划可以理解为总共走了m+n-2步,选择其中m-1往下走,n-1往右走,这就变成了组合问题。选择min(m-1.n-1)进行计算即可,时间复杂度为O(min(m-1.n-1)),空间复杂度为O(1)。
零钱兑换
You are given coins of different denominations and a total amount of money amount . Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return-1
.
Example:
Input: coins =[1, 2, 5]
, amount =11
Output:3
Explanation: 11 = 5 + 5 + 1
Code(By myself):
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
if amount == 0:
return 0
index = [0 for i in range(amount + 1)]
for i in coins:
if i <= amount:
index[i] = 1
for i in range(1,amount+1):
if index[i] == 0:
continue
for j in coins:
if i + j <= amount and (index[i+j] == 0 or index[i+j] > index[i] + 1):
index[i+j] =index[i] + 1
if index[amount] == 0:
return -1
return index[amount]
Code(others):
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
size = len(coins)
if size == 0:
return -1
if amount == 0:
return 0
coins.sort(reverse=True)
self.res = 2 ** 31
def dfs(remain, idx, cnt):
if remain == 0:
self.res = min(self.res, cnt)
return
for i in range(idx, size):
if coins[i] * (self.res - cnt) < remain:
return
elif coins[i] <= remain:
dfs(remain-coins[i], i, cnt+1)
for i in range(size):
if coins[i] * (self.res) < amount:
return self.res
elif coins[i] <= amount:
dfs(amount-coins[i], i, 1)
return self.res if (self.res < 2**31) else -1
总结:
利用递归先将最大的硬币使用最多次数,若不行则减少一枚大的,利用小的凑齐。
最长上升子序列
Given an unsorted array of integers, find the length of longest increasing subsequence.Example:
Input:[10,9,2,5,3,7,101,18]
Output: 4 Explanation: The longest increasing subsequence is[2,3,7,101]
, therefore the length is4
.
Code(By myself):
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 0:
return 0
maxLen = [1 for i in range(len(nums))]
maxLen = self.length(nums,maxLen)
return max(maxLen)
def length(self,nums,maxLen):
if len(nums) == 0:
return maxLen
if len(nums) == 1:
maxLen[0] = max(maxLen[0],1)
return maxLen
maxLen[1:] = self.length(nums[1:],maxLen[1:])
for i in range(1,len(nums)):
if nums[0] < nums[i]:
maxLen[0] = max(maxLen[0],maxLen[i]+1)
return maxLen
Code(others):
import bisect
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
q = [nums[0]]
for n in nums[1:]:
if n > q[-1]:
q.append(n)
else:
p = bisect.bisect_left(q, n)
q[p] = n
return len(q)
class Solution(object):
left = 0
right = 0
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if nums==[]:
return 0
ends = []
ends.insert(0,nums[0])
for i in range(1,len(nums)):
if nums[i]<ends[0]:
ends[0]=nums[i]
elif nums[i]>ends[-1]:
ends.append(nums[i])
else:
l = 0
r = len(ends)-1
while l<r:
mid = (l+r)/2
if ends[mid]<nums[i]:
l= mid + 1
else:
r = mid
ends[r] = nums[i]
return len(ends)
总结:
建立一个子序列表,遍历nums(),比子序列表最后一个元素大就加到最后,其他时替换相应位置元素。最后得出的最长子序列不一定时正确的子序列,但其长度时最长的子序列长度。
Above is a 7 x 3 grid. How many possible unique paths are there?
Note: m and n will be at most 100.