目录
- 3. 无重复字符的最长子串
- 53. 最大子数组和
- 80. 删除有序数组中的重复项 II
- 442. 数组中重复的数据
- 209. 长度最小的子数组
- 59. 螺旋矩阵 II
- 24. 两两交换链表中的节点
- 19. 删除链表的倒数第 N 个结点
- 142. 环形链表 II
3. 无重复字符的最长子串
滑动窗口,类似的题目还有绳子覆盖最多的点数
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# 滑动窗口问题
l,r = 0,0 # 定义窗口的左右边界
maxn = 0 # 记录最大值
while l <= len(s)-1: # 左边界可以一直试到最后一个位置
while (r+1 <= len(s)-1) and (s[r+1] not in s[l:r+1]): # r的增加不能超过右边界
r+=1
# 右边界停留在了合适的位置上,计算一下当前的长度吧
if r-l+1 > maxn:
maxn = r-l+1
l+=1 # 左边界滑动一格
return maxn
53. 最大子数组和
动态规划,解题思路看我的这篇博客
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# 记录最大和
max_sum = nums[0] #边界就是0号元素
# 直接用一个变量记录一下前边算出来的值,因为每个位置上只和前一个元素有关,省去dp数组
dp_cur = nums[0] #0号元素没法往前扩,只有一种选择,就是它自己就是累加和
for i in range(1, len(nums)):
dp_cur = max(dp_cur+nums[i], nums[i]) #”前边算出来的dp值+自身值“和”自身值“比大小
max_sum = max(max_sum, dp_cur)
return max_sum
80. 删除有序数组中的重复项 II
每个数需要和结果集中倒数第二个判断是否相等,是这题的解题关键,因为题目说允许两个数重复。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if len(nums)<=2:
return len(nums)
"""
#只管遍历数组即可,遇到合适的数就往前放(赋值),不合适的就不管这个数了
#那么前边就形成了一个好的结果集。
#往前放的时候不用担心,我们会设置一个变量在结果集尾,严格把控人员的进入
"""
# 设置一个看门的变量,前两个元素一定没问题,所以当前的队尾下标就是1
index = 1
# 查看数组中的每个元素(从第三个元素开始看就行),看能不能放行
for i in range(2, len(nums)):
if nums[i] != nums[index-1]: #当前数和结果集中倒数第二个数比较一下
nums[index+1] = nums[i]
index+=1
return index+1
442. 数组中重复的数据
这个题应该属于偏怪的技巧解题吧~~利用数值本身和索引之间的对应关系
class Solution:
def findDuplicates(self, nums: List[int]) -> List[int]:
"""
由于数组中的数是有固定范围的,可以对应映射到下标索引上。
那我们就可以通过操作下标索引位置的那个数,来折射出我们的需求
"""
# 存放找到的结果
res = []
# 遍历数组中的每个数
for num in nums:
index = abs(num)-1 #这个数的索引
#找到那个数nums[index]看一下
if nums[index] < 0: #说明之前有人访问过它了
res.append(abs(num)) #它不行,它是重复数
else: #第一次访问
nums[index] *= -1 #变成负数
return res
209. 长度最小的子数组
import math
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
# 想象成一个队列比较好理解
# 左边不需要一个一个往右扩,因为已经算过这一段的和了。
# 左边挨个削掉数,只需要减一下就算出来新的和了,不需要再重新累加,不断的削减就行
# 只需要定义几个全局变量就够了
left,right=0,0
curSum=0
minLength = 2*len(nums) # 表示一个很大的数
while right<len(nums): # 右边可以一直扩展
curSum+=nums[right] #往里放就行
right+=1 #右边界准备要放的下一个元素
# 只要变了我就判断一下当前的和
while curSum>=target:
minLength = right-left if right-left<minLength else minLength
curSum-=nums[left] # 左边削减
left+=1
return 0 if minLength==2*len(nums) else minLength
59. 螺旋矩阵 II
定义变量来控制走的边界,要比自己计算每次要走多少步,省事的多
【学习一下python中从大数到小数递减的for循环遍历,如何用range实现】
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
# 定义四个边界,边界控制我们要的走墙边的长度
# 沿着矩阵每走完一个墙边,边界就会压缩一下
# 这四个边界的值,刚好也能被用来作为访问数组的下标,也就是我们要走的那行/列
top,bottom,left,right = 0,n-1,0,n-1 #定义边界
count = 1 #计数
matrix = [[0 for x in range(n)] for x in range(n)]
while count <= n**2:
#沿着上边界右走
for i in range(left,right+1):
matrix[top][i] = count
count += 1
top += 1 #上边界压缩
#沿着右边界下走
for i in range(top,bottom+1):
matrix[i][right] = count
count += 1
right -= 1 #右边界压缩
#沿着下边界左走
for i in range(right,left-1,-1): # range(起点,终点,步长)
matrix[bottom][i] = count
count += 1
bottom -= 1 #下边界压缩
#沿着左边界上走
for i in range(bottom,top-1,-1):
matrix[i][left] = count
count += 1
left += 1 #左边界压缩
return matrix
24. 两两交换链表中的节点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head==None or head.next==None:
return head
else:
newHead = head.next #这是最终要返回的头
pre = head
while pre and pre.next: #保持有两个数
cur = pre.next
temp = cur.next
cur.next = pre #核心语句1
if temp==None or temp.next==None:
pre.next = temp
return newHead
else:
pre.next = temp.next #核心语句2
#往下走两格,进入到下一个循环
pre = temp
return newHead
19. 删除链表的倒数第 N 个结点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
nullHead = ListNode(0,head)
# 设立双指针cur、pre,想象两者之间构成一个程度为n的滑块
# 1、pre先走出n步,cur不动,两者之间的距离是n
# 2、一起走,当pre到末尾,cur指向的是倒数第n个
pre = nullHead
cur = nullHead
while n: #pre走到了正确的位置上
pre = pre.next
n -= 1
while pre.next!=None: #pre到最后一个节点时停止
pre = pre.next
cur = cur.next
cur.next = cur.next.next #核心语句
return nullHead.next #返回第一个实节点
142. 环形链表 II
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 设置快慢指针,快指针每次走两步,慢指针每次走一步
fast = head
slow = head
while fast and fast.next: # 如果是直链,一定会退出while循环的
fast = fast.next.next # 快指针大胆往前走两步
slow = slow.next # 慢指针走一步
if fast == slow: # 如果他俩相遇了,说明有环
#开始模拟,目的是找到环的入口
index1 = fast #相遇点
index2 = head #链表起点
while index1!=index2: #模拟俩人一起走的过程,最终一定会在环入口处相遇
index1 = index1.next
index2 = index2.next
return index1
return None
持续更新中……