class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
# 思路:hashmap存储每个字符最后出现的索引
if len(s) <= 1:
return len(s)
letter_map = {}
start = -1
res = 0
for i in range(len(s)):
if s[i] in letter_map.keys():
# 重点在于更新子串开始的起点为在字典出现的下一个索引
start = max(letter_map[s[i]],start)
letter_map[s[i]] = i
res = max(i - start, res)
return res
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
# 思路:模拟整个螺旋的路径
# 1.初始化左右上下边界的初始值
l, r, t, d = 0, len(matrix[0]) - 1, 0, len(matrix)-1
res = []
while True:
for i in range(l, r+1):
res.append(matrix[t][i])
#print(matrix[t][i])
t += 1
if t > d:
break
for i in range(t, d + 1):
res.append(matrix[i][r])
#print(matrix[i][r])
r -= 1
if r < l:
break
for i in range(r, l - 1, -1):
res.append(matrix[d][i])
#print(matrix[d][i])
d -= 1
if d < t:
break
for i in range(d, t - 1, -1):
res.append(matrix[i][l]) # 注意脑子里面要思考的是需要添加的元素是什么
#print(matrix[i][l])
l += 1
if l > r:
break
return res
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) <= 1:
return len(nums)
# 最长递增自序列
# 注意这里 不要求连续
# dp[i] 指的是以nums[i]结尾的最长自序列
dp = [1] * len(nums) # 注意长度的初始化 每个位置的长度最少都是自身为1
for i in range(1, len(nums)):
# 主要思路 如果不要求连续那么双重遍历前面的所有元素 如果比其大则加1
for j in range(0, i):
if nums[j] < nums[i]:
dp[i] = max(dp[j]+1, dp[i])
return max(dp)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
# 思路 用二分法 关键在于二分的左右端点怎么设置
# 1. 先找到最小值所在的index
minIndex = self.findMin(nums)
# 2. 通过与最后一个元素的比较判断在哪一段进行搜索
if target > nums[-1]:
left, right = 0, minIndex - 1
else:
left, right = minIndex, len(nums) - 1
# 3. 开始二分 注意条件<=
while left <= right:
mid = (left + right)/2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid -1
else:
left = mid + 1
return -1
def findMin(self, nums):
left, right = 0, len(nums) - 1
if len(nums)==1 or nums[0] < nums[-1]:
return 0
else:
while left <= right:
mid = (left + right) / 2
if nums[mid] >= nums[0]:
left = mid + 1
elif nums[mid] > nums[mid - 1]:
right = mid - 1
else:
return mid
return left
class Solution(object):
def minDistance(self, word1, word2):
"""
:type word1: str
:type word2: str
:rtype: int
"""
# 思路:对两个单词字符串的操作
# 二维动态规划
# 1.初始化矩阵
m = len(word1)
n = len(word2)
dp = [ [0] * (n + 1) for _ in range(m+1)]
# 2.初始化特殊值
for i in range(m+1):
dp[i][0] = i
for i in range(n+1):
dp[0][i] = i
# 3.遍历整个动态规划矩阵
for i in range(1, m+1):
for j in range(1,n+1):
if word1[i - 1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
# 增删都是1步 dp[i-1][j]+1 dp[i-1][j-1]是替换
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1] + 1, dp[i-1][j-1] + 1)
return dp[m][n]
!!!注意复习![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2670b14299e0450fa181c668708f0cd5.png)
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reorderList(self, head):
"""
:type head: ListNode
:rtype: None Do not return anything, modify head in-place instead.
"""
# 思路:
# 先用快慢指针找到链表的中点,然后将链表的后半部分反转,最后将左右两个链表合并
# 时间复杂度 O(n),其中 n 是链表的长度。空间复杂度 O(1)。
slow = fast = head
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
# 此时slow指针在链表中间
cur = slow.next
slow.next = None
# 反转右链表
pre = None
while cur:
t = cur.next
cur.next = pre
pre = cur
cur = t
# 此时右链表的头为pre
# 左链表
cur = head
# 合并cur和pre两个链表
while pre:
t = pre.next
pre.next = cur.next
cur.next = pre
cur, pre = pre.next, t