题1:两数之和 II - 输入有序数组
题目描述
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路&代码
有序数列,第一个想到是的二分查找
当然下面的代码并非二分查找,只是用了二分查找的思路
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
m, n = 0, len(numbers) - 1
while m < n:
if numbers[m] + numbers[n] > target:
n -= 1
elif numbers[m] + numbers[n] < target:
m += 1
else:
return [m+1, n+1]
看看成绩:
还可以,不得不说,二分查找真是LeetCode中的一大利器
题2:第三大的数
题目描述
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/third-maximum-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路&代码
这题肯定要排序,不过一旦涉及到排序,那复杂度就是O(n),也就是不能再有其他更复杂的操作了,想法是先去重,再排序,所以这题也蛮简单的
class Solution:
def thirdMax(self, nums: List[int]) -> int:
nums = list(set(nums))
nums.sort()
return nums[-3] if len(nums) >= 3 else nums[-1]
看看成绩:
这两题时间效率都提上去了,不过空间效率不咋地
题3:打家劫舍
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路&代码
这题一看,应该是考动态规划,我开始没太想明白到底该怎么规划,后来自己在纸上演算了一下,就明白了。
class Solution:
def rob(self, nums: List[int]) -> int:
if not nums:
return 0
if len(nums) <= 2:
return max(nums)
dp = [0] * len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, len(nums)):
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
return dp[len(nums)-1]
注意有两个边界条件,当数组为空的时候,返回0,当数组长度小于等于2时,返回数组中的最大值,剩下的就是动态规划的内容了。
看看成绩:
应该还有更优解,暂时想不出来了