01-两数之和(python)
#比较/排序+指针
class Solution:
def twosum(self,nums,target):
for i in range(len(nums)):
temp=nums[:i]
if (target-nums[i]) in temp:
j=temp.index(target-nums[i])
break
return [j,i]
03-无重复字符最长子串(python)
#滑动窗口
class Solution:
def lengthOfLongestSubString(self,s):
if not s:return 0
lookup=set()
max_len=0
cur_len=0
left=0
for i in range(len(s)):
cur_len+=1
while s[i] in lookup:
lookup.remove(s[left]
cur_len+=1
if cur_len>max_len:
max_len=cur_len
lookup.add(s[i])
return max_len
05-最长回文子串(python)
#动态规划-边界条件
class Solution:
def longestPalindrome(self,s):
size=len(s)
if size<=1:
return s
longest_l=1
res=s[0]
dp=[[False for _ in range(size)] for _ in range(size)]
for r in range(1,size):
for l in range(r):
if s[l] == s[r]:
if r - l < 3:
dp[l][r] = True
else:
dp[l][r] = dp[l + 1][r - 1]
else:
dp[l][r] = False
if dp[l][r]:
cur_len = r - l + 1
if cur_len > longest_l:
longest_l = cur_len
res = s[l:r + 1]
return res
010-正则表达式匹配(python)
class Solution(object):
def isMatch(self, s, p):
if not p: return not s
if not s and len(p) == 1: return False
m, n = len(s) + 1, len(p) + 1
dp = [[False for _ in range(n)] for _ in range(m)]
# 初始状态
dp[0][0] = True
dp[0][1] = False
for c in range(2, n):
j = c - 1
if p[j] == '*':
dp[0][c] = dp[0][c - 2]
for r in range(1,m):
i = r - 1
for c in range(1, n):
j = c - 1
if s[i] == p[j] or p[j] == '.':
dp[r][c] = dp[r - 1][c - 1]
elif p[j] == '*': # ‘*’前面的字符匹配s[i] 或者为'.'
if p[j - 1] == s[i] or p[j - 1] == '.':
dp[r][c] = dp[r - 1][c] or dp[r][c - 2]
else: # ‘*’匹配了0次前面的字符
dp[r][c] = dp[r][c - 2]
else:
dp[r][c] = False
return dp[m - 1][n - 1]
011-盛最多水的容器(python)
#双指针-移除短板
class Solution:
def maxArea(self,height):
i,j,res=0,len(height),0
while i<j:
if height[i]<height[j]:
res=max(res,height[i]*(j-i))
i+=1
else:
res=max(res,height[j]*(j-i))
j-=1
return res
015-三数之和(python)
#排序+双指针
class Solution:
def threeSum(self, nums):
nums.sort()
res, k = [], 0
for k in range(len(nums) - 2):
if nums[k] > 0:
break # 1. because of j > i > k.
if k > 0 and nums[k] == nums[k - 1]:
continue # 2. skip the same `nums[k]`.
i, j = k + 1, len(nums) - 1
while i < j: # 3. double pointer
s = nums[k] + nums[i] + nums[j]
if s < 0:
i += 1
while i < j and nums[i] == nums[i - 1]:
i += 1
elif s > 0:
j -= 1
while i < j and nums[j] == nums[j + 1]:
j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i - 1]:
i += 1
while i < j and nums[j] == nums[j + 1]:
j -= 1
return res
017-电话号码的字母组合(python)
#回溯
class Solution:
def letterCombinations(self, digits):
phone = {'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']}
output=[]
def backtrack(combination, next_digits):
if len(next_digits)==0:
output.append(combination)
else:
for letter in phone[next_digits[0]]:
backtrack(combination+letter,next_digits[1:])
if digits:
backtrack('',digits)
return output
019-删除链表倒数第n个节点(python)
#快慢指针、求链表需要先建空链表
class Solution:
def removeNthFromEnd(self, head, n):
if not head:return
dummy=ListNode(0)
dummy.next=head
fast=dummy
slow=dummy
for i in range(n):
fast=fast.next
while fast and fast.next:
fast=fast.next
slow=slow.next
slow.next=slow.next.next
return dummy.next
020-有效的括号(python)
class Solution:
def isValid(self, s):
mapping={")":"(","]":"[","}":"{"}
stack=[]
for char in s:
if char not in mapping:
stack.append(char)
else:#判断右括号
top_element=stack.pop()
if top_element!=mapping[char]:
return false
return not stack
21-合并两个有序链表(python)
class Solution:
def mergeTwoLists(self, l1, l2):
prev=ListNode(0)
prehead=prev
while l1 and l2:
if l1.val<=l2.val:
prehead.next=l1
l1=l1.next
else:
prehead.next=l2
l2=l2.next
prehead=prehead.next
prehead.next=l1 if l1 is not None else l2
return prev.next
22-括号生成(python)
#回溯
class Solution:
def generateParenthesis(self,n):
ans=[]
def backtrack(S='',left=0,right=0):
if len(s)==2*n:
ans.append(S)
if left<n:backtrack(S='(',left+1,right)
if right<left:backtrack(S=')',left,right+1)
backtrack()
return ans
23-合并k个有序链表(python)
#分治,先合并2个
class Solution:
def mergeKLists(self, lists):
if not lists:return
n = len(lists)
return self.merge(lists, 0, n-1)
def merge(self,lists, left, right):
if left == right:
return lists[left]
mid = (left + right) // 2
l1 = self.merge(lists, left, mid)
l2 = self.merge(lists, mid+1, right)
return self.mergeTwoLists(l1, l2)
def mergeTwoLists(self, l1, l2):
prev=ListNode(0)
prehead=prev
while l1 and l2:
if l1.val<=l2.val:
prehead.next=l1
l1=l1.next
else:
prehead.next=l2
l2=l2.next
prehead=prehead.next
prehead.next=l1 if l1 is not None else l2
return prev.next
31-下一个排列(python)
#倒序查找第一个减小的索引,排序后,与第一个较大的值做交换。
class Solution:
def nextPermutation(self, nums) :
for i in range(len(nums)-1, 0, -1):
if nums[i] > nums[i-1]:
res_nums = nums[i:]
res_nums.sort()
nums[i:] = res_nums
for j in range(i, len(nums)):
if nums[j] > nums[i-1]:
nums[j], nums[i-1] = nums[i-1], nums[j]
return nums
nums.sort()
return nums
32-最长有效的括号(python)
class Solution:
def longestValidParenthesis(self,s):
maxnum=0
stack=[-1]
for i in range(len(s)):
if s[i]=='(':stack.append(i)
else:
stack.pop()
if not stack:stack.append(i)
if stack:maxnum=max(maxnum,i-stack[-1])
return maxnum
33-搜索旋转排序数组(python)
#找下降索引,二分查找
class Solution:
def search(self, nums, target):
def find_rotate_index(left, right):
if nums[left] < nums[right]:
return 0
while left <= right:
pivot = (left + right) // 2
if nums[pivot] > nums[pivot + 1]:
return pivot + 1
else:
if nums[pivot] < nums[left]:
right = pivot - 1
else:
left = pivot + 1
def search(left, right):
while left <= right:
pivot = (left + right) // 2
if nums[pivot] == target:
return pivot
else:
if target < nums[pivot]:
right = pivot - 1
else:
left = pivot + 1
return -1
n = len(nums)
if n == 0:
return -1
if n == 1:
return 0 if nums[0] == target else -1
rotate_index = find_rotate_index(0, n - 1)
if nums[rotate_index] == target:
return rotate_index
if rotate_index == 0:
return search(0, n - 1)
if target < nums[0]:
return search(rotate_index, n - 1)
else:
return search(0, rotate_index)
34-在排序数组中查找元素的第一个和最后一个位置(python)
#二分查找(有重复值)
class Solution(object):
def searchRange(self, nums, target):
length = len(nums)
if length == 0:
return [-1,-1]
left,right = 0,length-1
while left <= right:
mid = (left+right) // 2
if nums[mid] == target:
right = left = mid
while left-1 >= 0 and nums[left-1] == target:
left -= 1
while right+1 <= length-1 and nums[right+1] == target:
right += 1
return [left,right]
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return [-1,-1]
39-组合总数(python)
#深度优先
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
size=len(candidates)
if size==0:
return []
candidates.sort()
path=[]
res=[]
self.dfs(candidates,0,size,path,res,target)
return res
def dfs(self,candidates,start,size,path,res,target):
if target==0:
res.append(path[:])
return
for index in range(start,size):
ram=target-candidates[index]
if ram<0:
break
path.append(candidates[index])
self.dfs(candidates,index,size,path,res,ram)
path.pop()
042-接雨水(python)
#双指针法
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
if not height:return 0
n=len(height)
ans=0
left,right=0,n-1
max_left,max_right=height[0],height[n-1]
while left<right:
max_left=max(max_left,height[left])
max_right=max(max_right,height[right])
if max_left<max_right:
ans+=max_left-height[left]
left+=1
else:
ans+=max_right-height[right]
right-=1
return ans
46-全排列(python)
#递归+交换
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def backtrack(first=0):
if first==n:
output.append(nums[:])
for i in range(first,n):
nums[first],nums[i]=nums[i],nums[first]
backtrack(first+1)
nums[first],nums[i]=nums[i],nums[first]
output=[]
n=len(nums)
backtrack()
return output
48-旋转图像(python)
class Solution:
def rotate(self,matrix):
n=len(matrix)
for i in range(n):
for j in range(i,n):
matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j]
for i in range(n):
matrix[i].reverse()
return matrix
128-最长连续序列(python)
class Solution:
def longestConsecutive(self,nums):
if not nums:return 0
nums.sort()
longest_streak=1
current_streak=1
for i in range(1,len(nums)):
if nums[i]!=nums[i-1]:
if nums[i]==nums[i-1]+1:
current_streak+=1
else:
longest_streak=max(longest_streak,current_streak)
current_streak=1
return max(longest_streak,current_streak)