题目1
- 题号:16
- 难度:中等
- https://leetcode-cn.com/problems/3sum-closest/
给定一个包括n
个整数的数组nums
和一个目标值target
。找出nums
中的三个整数,使得它们的和与target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例 :
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
思路1
这题和三数之和接近,就是排序然后再使用双指针。寻找最接近的数,刚好原来的三数之和就是使用慢慢接近的方法寻找target的,所以就可以在寻找target的过程中每一次都判断是否是最接近的。
优化的细节是在双指针前加入当前这一轮,也就是first固定下来后的最大值和最小值与target的关系。如果最大的数都小于等于target,那直接下一轮,first往右也许能更大;如果最小的数都大于等于target,那压根别找了,因为不可能再有更小的数了,直接Break掉返回结果即可。
实现1
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
n = len(nums)
nums.sort() # 排序
ans = float('inf') # 无穷大
for first in range(n-2): # 枚举第一个元素
if first > 0 and nums[first] == nums[first-1]:
continue # 保证first不会有重复
second, third = first + 1, n - 1
max_sum = nums[first] + nums[-2] + nums[-1]
min_sum = nums[first] + nums[first + 1] + nums[first + 2]
if max_sum <= target: # 最大的数
if abs(max_sum - target) < abs(ans - target): # 当前差距和最小差距的比较
ans = max_sum
continue
elif min_sum >= target: # 最小的数
if abs(min_sum - target) < abs(ans - target):
ans = min_sum
break
while second < third:
two_sum_target = target - nums[first]
s = nums[second] + nums[third]
if abs(s + nums[first] - target) < abs(ans - target):
ans = s + nums[first]
if s > two_sum_target: # 当前数值太大 右指针左移
third -= 1
while third > second and nums[third] == nums[third + 1]:
third -= 1
elif s < two_sum_target: # 当前数值太小 左指针右移
second += 1
while third > second and nums[second] == nums[second - 1]:
second += 1
else: # 刚好等于 直接返回target即可
return target
return ans
题目2
- 题号:20
- 难度:简单
- https://leetcode-cn.com/problems/valid-parentheses/
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
示例 6:
输入: ""
输出: true
示例 7:
输入: "(("
输出: false
思路1
栈
先出现的左括号后匹配,在python中列表可以当作栈!然后使用.pop()来弹出最后一个元素,.append()是加入元素。
实现1
class Solution:
def isValid(self, s: str) -> bool:
if len(s)%2==1: # 长度是奇数的话不用判断
return False
dic = {')':'(',']':'[','}':'{'}
stack = []
for i in s:
if stack and i in dic: # 匹配到右括号并且栈中有元素
if stack[-1] == dic[i]: # 栈的最后一个元素就是对应左括号
stack.pop() # 弹出
else:
return False
else:
stack.append(i) # 将先出现的左括号加入
return not stack
时间复杂度O(n) 只遍历了一遍字符串
题目3
- 题号:21
- 难度:简单
- https://leetcode-cn.com/problems/merge-two-sorted-lists/
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
思路1
递归实现
合并的时候比较大小即可
实现1
class Solution:
def mergeTwoLists(self, l1, l2):
if l1 is None:
return l2
elif l2 is None:
return l1
elif l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next)
return l2