1、寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
示例 1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
class Solution:
def findPeakElement(self, nums: list[int]) -> int:
nums.append(-float('inf'))
low , high = 0 , len(nums) - 1
while low < high:
mid = (low + high) // 2
if nums[mid] < nums[mid + 1]:
low = mid + 1
else:
high = mid
return low
if __name__ == '__main__':
solu = Solution()
nums = [1,2,3,1]
print(solu.findPeakElement(nums))
2、删除链表中的重复元素
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例 1:
输入:head = [1,1,2]
输出:[1,2]
示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
cur = head
while cur and cur.next:
if cur.val == cur.next.val: cur.next = cur.next.next
else: cur = cur.next
return head
3、删除链表中的重复元素 2
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
# 方法一:递归+迭代
from logging import root
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
if not root or not head.next:
return head
if head.next != head.next.val :
head.next = self.deleteDuplicates(head.next)
else:
new = head.next
while new and new.val == head.val :
new = new.next
return self.deleteDuplicates(new)
return head
# 方法二:双指针
"""
①
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
thead = ListNode('a')
thead.next = head
pre,cur = None,thead
while cur:
pre=cur
cur=cur.next
while cur and cur.next and cur.next.val == cur.val:
t=cur.val
while cur and cur.val==t:
cur=cur.next
pre.next=cur
return thead.next
②
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
new = ListNode(0)
new.next = head
pre = new
cur = head
while cur:
if cur.val != cur.next.val:
pre = cur
cur = cur.next
else:
while cur.next and cur.val == cur.next.val:
cur = cur.next
cur = cur.next
if not cur or not cur.next or cur.val != cur.next.val :
pre.next = cur
pre = cur
if cur :
cur = cur.next
return new.next
"""
4、三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
n = len(nums)
res = []
# 数组为 null 或者数组长度小于 3,返回 []
if (not nums) or (n < 3):
return []
# 对数组进行排序
nums.sort()
# 若 nums[0]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回[]
if (nums[0] > 0):
return []
# 遍历排序后数组:
for i in range(n):
# 对于重复元素:跳过,避免出现重复解
if (i > 0 and nums[i] == nums[i - 1]):
continue
L = i + 1
R = n - 1
# 令左指针 L=i+1,右指针 R=n-1,当 L<R 时,执行循环:
while (L < R):
if (nums[i] + nums[L] + nums[R] == 0):
res.append([nums[i], nums[L], nums[R]])
# 当 nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解
while (L < R and nums[L] == nums[L + 1]):
L = L + 1
while (L < R and nums[R] == nums[R - 1]):
R = R - 1
# 并同时将 L,R 移到下一位置,寻找新的解
L = L + 1
R = R - 1
# 若和大于 0,说明 nums[R] 太大,R 左移
elif (nums[i] + nums[L] + nums[R] > 0):
R = R - 1
# 若和小于 0,说明 nums[L] 太小,L 右移
else:
L = L + 1
return res
if __name__ == '__main__':
solu = Solution()
nums = [-1,0,1,2,-1,-4]
print(solu.threeSum(nums))
5、比较含退格的字符串
给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。
示例 2:
输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。
示例 3:
输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
i = len(s) - 1
j = len(t) - 1
num_s = num_t = 0
while i >= 0 or j >= 0:
while i >= 0:
if s[i] == "#":
num_s += 1
i -= 1
elif num_s > 0:
num_s -= 1
i -= 1
else:
break
while j >= 0:
if t[j] == "#":
num_t += 1
j -= 1
elif num_t > 0:
num_t -= 1
j -=1
else:
break
if i >= 0 and j >= 0:
if s[i] != t[j]:
return False
elif i >= 0 or j >= 0:
return False
"""
s = "" if i < 0 else S[i]
t = "" if j < 0 else T[j]
if s != t:
return False
"""
i -= 1
j -= 1
return True
if __name__ == '__main__':
solu = Solution()
s = "a#c"
t = "#b"
print(solu.backspaceCompare(s,t))
6、区间列表的交集
给定两个由一些 闭区间 组成的列表,firstList 和 secondList ,其中 firstList[i] = [starti, endi] 而 secondList[j] = [startj, endj] 。每个区间列表都是成对 不相交 的,并且 已经排序 。
返回这 两个区间列表的交集 。
形式上,闭区间 [a, b](其中 a <= b)表示实数 x 的集合,而 a <= x <= b 。
两个闭区间的 交集 是一组实数,要么为空集,要么为闭区间。例如,[1, 3] 和 [2, 4] 的交集为 [2, 3] 。
示例 1:
输入:firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
输出:[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
示例 2:
输入:firstList = [[1,3],[5,9]], secondList = []
输出:[]
示例 3:
输入:firstList = [], secondList = [[4,8],[10,12]]
输出:[]
示例 4:
输入:firstList = [[1,7]], secondList = [[3,10]]
输出:[[3,7]]
# 方法一 :双指针
class Solution:
def intervalIntersection(self, firstList: list[list[int]], secondList: list[list[int]]) -> list[list[int]]:
ans = []
f, s = firstList, secondList
L, R = 0, 0
while L < len(firstList) and R < len(secondList):
if s[R][0] > f[L][-1]: #区间不重合且L更小
L += 1
elif f[L][0] > s[R][-1]: #区间不重合且R更小
R += 1
else:
if f[L][0] <= s[R][0]:
if f[L][1] >= s[R][1]: #情况1
ans.append([s[R][0], s[R][1]])
R += 1
elif f[L][1] <= s[R][1]: #情况2
ans.append([s[R][0], f[L][1]])
if f[L][1] == s[R][1]:
L += 1
R += 1
else:
L += 1
elif f[L][1] == s[R][0]: #情况3
ans.append([s[R][0], s[R][0]])
L += 1
else:
if f[L][1] >= s[R][1]: #情况1
ans.append([f[L][0], s[R][1]])
R += 1
elif f[L][1] <= s[R][1]: #情况2
ans.append([f[L][0], f[L][1]])
if f[L][1] == s[R][1]:
L += 1
R += 1
else:
L += 1
elif f[L][0] == s[R][1]: #情况3
ans.append([f[L][0], f[L][0]])
L += 1
return ans
"""
方法二:pop
"""