文章目录
- 3. Longest Substring Without Repeating Characters
- 4. Median of Two Sorted Arrays
- 5.Longest Palindromic Substring
- 11.Container With Most Water
- 15. 3Sum:
- 17. Letter Combinations of a Phone Number
- 19. Remove Nth Node From End of List:
- 21. Merge Two Sorted Lists
- 22.Generate Parentheses
- 23.Merge k Sorted List:
- 31.Next Permutation
- 32. Longest Valid Parentheses
- 33.Search in Rotated Sorted Array:
- 34.Find First and Last Position of Element in Sorted Array
- 39.Combination Sum:
- 40.组合总和II:
- 42.Trapping Rain Water
- 46.Permutations
- 48.Rotate Image
- 49. Group Anagrams
- 53.Maximum Subarray
- 55. Jump Game:
- 56. Merge Intervals
- 62. Unique Paths
- 64. Minimum Path Sum
- 70. Climbing Stairs
- 72. Edit Distance
- 75. Sort Colors
- 76. Minimum Window Substring
- 78. 子集
- 84. Largest Rectangle in Histogram
- 90.子集II:
- 94. Binary Tree Inorder Traversal
- 102. 二叉树的层次遍历:
- 104.二叉树的最大深度:
- 111. 二叉树的最小深度:
- 121.Best Time to Buy and Sell Stock:
- 122. Best Time to Buy and Sell Stock II
- 128. Longest Consecutive Sequence
- 136.Single Number
- 141. Linked List Cycle
- 142. Linked List Cycle II
- 152.Maximum Product Subarray
- 155.Min Stack
- 160.Intersection of Two Linked Lists
- 169.求众数:
- 198.打家劫舍:
- 200. 岛屿的个数:
- 206.反转链表:
- 208.实现前缀树:
- 215.数组中的第k个最大元素
- 222.完全二叉树的节点:
- 226.翻转二叉树
- 232.用栈实现队列:
- 234.回文链表:
- 238.Product of Array Except Self
- 239.滑动窗口最大值
- 240.搜索二维矩阵 II:
- 284.移动零:
- 287.寻找重复数
- 409.Longest Palindrome
- 438. 找到字符串中所有字母异位词
- 448.找到所有数组中消失的数字:
- 461.汉明距离:
- 494. 目标和
- 581.最短无序连续子数组:
- 617.合并二叉树:
- 647. Palindromic Substrings
- 771. Jewels and Stones
题目 | 难度 | 复杂度 | 解法 | 备注 |
---|---|---|---|---|
3. Longest Substring Without Repeating Characters | Medium | 遍历哈希表保存每个字符的初始位置 | ToDo | |
4. Median of Two Sorted Arrays | Medium | 传统解法+中位数的数学推导 | ||
5.Longest Palindromic Substring | Medium | 暴力解法,遍历然后判断每个子字符串是否为回文 | Done | |
11. Container With Most Water | Medium | 暴力解法获取每个区间,求最大;双指针,从外向里移动 | Done | |
15. 3Sum | Medium | 双指针 | ||
17. Letter Combinations of a Phone Number | Medium | 递归 | ||
19. Remove Nth Node From End of List | Medium | 设置哑结点 | ||
21. Merge Two Sorted Lists | Easy | 设置哑节点,然后类似list,依次选择较小的一个 | Done | |
22.Generate Parentheses | Medium | 暴力做法;回溯法,前面的序列有效时才增加"(“或”)" | ||
23.Merge k Sorted Lists | Hard | 暴力法;分置变成爽链表问题 | ToDo | |
31.Next Permutation | Medium | 暴力法;遍历,替换 | ToDo | |
32.Longest Valid Parentheses | Hard | 暴力法;数学规律 | ToDo | |
33.Search bia Rotated Sorted Array | Medium | 遍历; | Done | |
34.Find First and Last Position of Element in Sorted Array | Medium | 遍历;二分查找 | Done | |
39.Combination Sum | Medium | 递归 | ToDo | |
42. Trapping Rain Water | Hard | 暴力;双指针 | ToDO | |
46.Permutations | Medium | 递归 | ToDo | |
48. | Medium | 翻转然后转置 | Done | |
53. Maximum Subarray | Easy | 遍历所有子序列; | Done | |
55. Jump Game | Medium | 贪心法,从右到左 | ToDo | |
56. Merge Intervals | Medium | 排序,然后进行区间合并 | Done | |
62. Unique Paths | Medium | 一共m+n-2步,选择m-1种向下的走法;DP | ToDo | |
64. Minimum Path Sum | Medium | 动态规划 | ToDo | |
70.Climbing Stairs | Easy | 斐波那契数列 | ToDo | |
72.Edit Distance | Hard | Medium | 动态规划 | |
75. Sort Colors | Medium | 直接排序,或者对0,2进行操作 | Done | |
76. Minimum Window Substring | Hard | 双指针+滑动窗口 | ToDo | |
84. Largest Rectangle in Histogram | Hard | ToDo | ||
94. Binary Tree Inorder Traversal | Medium | 递归和非递归方法 | ToDo | |
102.二叉树的层次遍历 | Medium | 队列保存每个结点 | ToDo | |
121. Best Time to Buy and Sell Stock | Easy | 暴力; 一次遍历,依次当前值前面的最小值 | Done | |
122. Best Time to Buy and Sell Stock II | Easy | 暴力法和一次遍历 | ToDo | |
128. Longest Consecutive Sequence | Hard | 排序后遍历 | ToDo | |
141. Linked List Cycle | Easy | 哈希表或者快慢指针 | ||
142. Linked List Cycle II | Medium | 哈希表或者快慢指针 | ||
152.Maximum Product Subarray | Medium | 暴力法;前后遍历,得到乘积 | Done | |
155. Min Stack | Easy | 建立辅助栈 | Done | |
160.相交链表 | Easy | 遍历 | ToDo | |
169.求众数 | Easy | 哈希表保存出现次数 | Done | |
198. 打家劫舍 | Easy | 动态规划 | ToDo | |
200. 岛屿的个数 | Medium | DFS | ToDo | |
206.反转链表 | Easy | 数据格式不清楚 | ToDo | |
208.实现前缀树 | Medium | 直接实现 | Done | |
215. 数组中的第K个最大元素 | Medium | 排序,然后求解 | Done | |
221.最大正方形 | Medium | ToDo | ||
226.翻转二叉树 | Easy | 递归,翻转 | Done | |
234.回文链表 | Easy | 保存在list中然后判断是否是回文 | Done | |
236.二叉树的最近公共祖先 | Medium | ToDo | ||
238.除自身以外的数组的乘积 | Medium | 除法;前后累积乘积 | ToDo | |
239.滑动窗口最大值 | Hard | 滑动遍历求最值; | Done | |
240.搜索二维矩阵 | Medium | 观察规律 | Done | |
279.完全平方数 | Medium | Todo | ||
283.移动零 | Medium | 遍历,去除,保存 | Done | |
287.寻找重复数 | Medium | 哈希表保存次数 | Done | |
297. 二叉树的序列化与反序列化 | Hard | Done | ||
300.最长上升子序列 | Medium | ToDo | ||
309.最佳买卖股票时机含冷冻期 | Medium | ToDo | ||
312. 戳气球 | Hard | ToDo | ||
322.零钱兑换 | Medium | 动态规划 | ToDo | |
409. Longest Palindrome | Easy | 统计次数,判断奇偶 | Done | |
461.汉明距离 | Easy | 异或然后判断二进制中1的个数 | Done | |
494. 目标和 | Medium | DFS | ToDo | |
581. 最短无序连续子数组 | Easy | 排序然后遍历比较 | Done | |
617.合并二叉树 | Medium | 递归;循环 | Done | |
647. 回文子串 | Medium | 暴力解法;遍历字符串以每个字符为中心 | Done | |
771. Jewels and Stones | Easy | 巨简单 |
3. Longest Substring Without Repeating Characters
暴力解法,遍历所有子字符串,然后判断所有字符串是否重复,求不重复的最大值
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
if s == '':
return 0
if len(s) == 1:
return 1
len_list = []
for i in range(len(s)-1):
for j in range(i+1, len(s)+1):
temp = s[i:j]
# print(temp)
if len(set(temp)) == len(temp):
len_list.append(len(temp))
return max(len_list)
用一个Hash表保存每一个char出现的位置,如果出现重复,那么将这个char重复出现的位置和第一次出现的位置相减。
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
char_dict = {}
start = 0
maxlen = 0
for index, char in enumerate(s):
if char in char_dict and char_dict[char] >= start:
maxlen = max(maxlen, index-start)
start = char_dict[char] + 1
char_dict[char] = index
return max(maxlen, len(s)-start)
4. Median of Two Sorted Arrays
暴力解法,4ms
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums1.extend(nums2)
length = len(nums1)
nums1 = sorted(nums1)
if len(nums1)%2 == 0:
return (nums1[int(length/2)-1] + nums1[int(length/2)])/2
else:
return nums1[int((length-1)/2)]
5.Longest Palindromic Substring
暴力解法,遍历然后判断是否是回文。
class Solution:
def longestPalindrome(self, string):
"""
:type s: str
:rtype: str
"""
length = len(string)
max_len = 0
result = ''
if len(string) == 1:
return string
for i in range(length):
for j in range(i+1,length+1):
temp = string[i:j]
# print(temp,i,j)
if temp == temp[::-1] and len(temp) > max_len:
max_len = len(temp)
result = temp
return result
遍历字符串,以单个字符为中心向外延展,取字符串长度最长的。考虑”aba“和”abba“这两种情况。
class Solution(object):
def longestPalindrome(self, s):
res = ""
for i in range(len(s)):
# odd case, like "aba"
tmp = self.helper(s, i, i)
if len(tmp) > len(res):
res = tmp
# even case, like "abba"
tmp = self.helper(s, i, i+1)
if len(tmp) > len(res):
res = tmp
return res
# get the longest palindrome, l, r are the middle indexes
# from inner to outer
def helper(self, s, l, r):
while l >= 0 and r < len(s) and s[l] == s[r]:
l -= 1; r += 1
return s[l+1:r]
11.Container With Most Water
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
maxarea = 0
for i in range(len(height)-1):
for j in range(i+1, len(height)):
area = (j-i)*min(height[i],height[j])
if area > maxarea:
maxarea = area
return maxarea
双指针,从两边向里移动,移动start和end中小的那一个
class Solution:
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
max_area,left,right = 0,0,len(height)-1
while(left < right):
max_area = max(max_area, (right-left)*min(height[left], height[right]))
if height[left] < height[right]:
left += 1
else:
right -= 1
return max_area
15. 3Sum:
暴力解法,
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if len(nums) < 3:
return
result = []
nums = sorted(nums)
result_str = []
for i in range(len(nums) - 2):
for j in range(i+1, len(nums) - 1):
for k in range(j+1, len(nums)):
result1 = ''.join([str(nums[i]),str(nums[j]), str(nums[k])])
if nums[i] + nums[j] + nums[k] == 0 and result1 not in result_str:
result.append([nums[i],nums[j], nums[k]])
result_str.append(result1)
return result
双指针,做成Two-Sum问题:
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums = sorted(nums)
result = []
for i in range(len(nums)-2):
if i > 0 and nums[i] == nums[i-1]:
continue
left = i+1
right = len(nums) - 1
while left < right:
sum1 = nums[i] + nums[left] + nums[right]
if sum1 < 0:
left += 1
elif sum1 == 0:
result.append([nums[i],nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left-1]:
left += 1
while right > left and nums[right] == nums[right+1]:
right -= 1
else:
right -= 1
return result
17. Letter Combinations of a Phone Number
采用递归来写,
class Solution(object):
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
kvmaps = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
}
if len(digits) == 0:
return []
if len(digits) == 1:
return list(kvmaps[digits[0]])
return [str1 + char1 for str1 in self.letterCombinations(digits[:-1]) for char1 in kvmaps[digits[-1]]]
19. Remove Nth Node From End of List:
首先确定链表的长度L,删除倒数第N个,即删除正数第L-N+1个;
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(0)
length = 0
dummy.next = head
first = head
while first != None:
length += 1
first = first.next
length -= n
first = dummy
while length > 0:
length -= 1
first = first.next
first.next = first.next.next
return dummy.next
两个指针,第一个指针走n个后,另一个指针再开始,第一个指针到最后的时候,第二个指针到达倒数第n个。
class Solution(object):
def removeNthFromEnd(self, head, n):
dummy = ListNode(0)
dummy.next = head
first = dummy
second = dummy
for i in range(n+1):
first = first.next
while first != None:
first = first.next
second = second.next
second.next = second.next.next
return dummy.next
21. Merge Two Sorted Lists
遍历链表,设置哑结点,遍历两个链表,从小到大排序。
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
result = ListNode(0)
current = result
while l1 != None and l2 != None:
if l1.val < l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l2.next
current = current.next
if l1 == None:
current.next = l2
else:
current.next = l1
return result.next
def mergeTwoLists1(self, l1, l2):
dummy = cur = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
cur.next = l1 or l2
return dummy.next
22.Generate Parentheses
暴力做法,生成所有的表示“()”字符构成的序列,然后判断该字符是否是有效的。通过递归来生成所有的序列。平衡字符来判断该序列是否是有效的。
class Solution(object):
# 148ms
# 13.5MB
def generateParenthesis(self, n):
def generate(A = []):
if len(A) == 2*n:
if valid(A):
ans.append("".join(A))
else:
A.append('(')
generate(A)
A.pop()
A.append(')')
generate(A)
A.pop()
def valid(A):
bal = 0
for c in A:
if c == '(': bal += 1
else: bal -= 1
if bal < 0: return False
return bal == 0
ans = []
generate()
return ans
回溯法:当当前序列有效时才增加新的括号“()”。判断的标准是左括号的数目,保证左括号数量小于N,如果右括号数量小于左括号数目那么增加右括号数目。
class Solution(object):
# 56ms
# 13.4MB
def generateParenthesis(self, N):
ans = []
def backtrack(S = '', left = 0, right = 0):
if len(S) == 2 * N:
ans.append(S)
return
if left < N:
backtrack(S+'(', left+1, right)
if right < left:
backtrack(S+')', left, right+1)
backtrack()
return ans
23.Merge k Sorted List:
暴力法 :保存所有链表的数值,然后对其进行排序,将排序后的list转换成链表。相当于对一个二维list进行排序。
class Solution(object):
# 88ms
# 20MB
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
all_list = []
head = point = ListNode(0)
for List in lists:
while List:
all_list.append(List.val)
List = List.next
all_list = sorted(all_list)
for num in all_list:
point.next = ListNode(num)
point = point.next
return head.next
分置算法:
将这k个排序链表一分为二,不断持续下去,将其变成双链表合并问题。
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if not lists:
return []
if len(lists) == 1:
return lists[0]
mid = len(lists) // 2
ll = self.mergeKLists(lists[:mid])
rl = self.mergeKLists(lists[mid:])
return self.merge2List(ll,rl)
def merge2List(self, l, r):
root = ListNode(0)
cur = root
while l and r:
if l.val < r.val:
cur.next = l
l = l.next
cur = cur.next
else:
cur.next = r
r = r.next
cur = cur.next
if l:
cur.next = l
else:
cur.next = r
return root.next
31.Next Permutation
暴力法:
生成所有可能的排列情况,然后找到最接近的那个排列。
从右到左遍历list,如果第i个数比第i+1数小,那么这个数应该被替换。这个数的右边是一个递减序列。将这个数替换成右边序列比第i个数大,但最接近的那个。然后将右边的数做逆序排列。
class Solution:
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
i = len(nums) - 2
while i >= 0 and nums[i] >= nums[i+1]:
i -= 1
if i>=0:
j = len(nums) - 1
while j >=0 and nums[i] >= nums[j]:
j -= 1
temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
nums[i+1:] = nums[i+1:][::-1]
32. Longest Valid Parentheses
暴力法,生成所有的子序列,然后判断是否是有效序列,保存有效序列的长度,求最值:
class Solution:
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
def Isvalid(s):
num = 0
for char in s:
if char == '(':
num += 1
else:
num -= 1
if num < 0:
return False
return num == 0
result = []
for i in range(len(s)-1):
for j in range(i+1, len(s)+1):
temp_s = s[i:j]
if Isvalid(temp_s):
result.append(len(temp_s))
if result == []:
return 0
return max(result)
利用数学规律,首先从左到右遍历,遇到“(”,left+1,遇到")",right+1。如果left和right再次相等,则为有效序列,判断其是否为最长序列,同时令left和right均为0,如果right>left也置零。从右到左做同样的遍历。
# 52 ms
# 13.2 Mb
class Solution(object):
def longestValidParentheses(self, s):
"""
:type s: str
:rtype: int
"""
left,right,maxlength = 0,0,0
for i in range(len(s)):
if s[i] == '(':
left += 1
else:
right += 1
if left == right:
maxlength = max(maxlength, 2*right)
elif right > left:
left = 0
right = 0
left = right = 0
for i in range(len(s)-1,-1,-1):
if s[i] == '(':
left += 1
else:
right += 1
if left == right:
maxlength = max(maxlength, 2*left)
elif left >= right:
left = right = 0
return maxlength
33.Search in Rotated Sorted Array:
遍历list,然后得到index:
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if target not in nums:
return -1
return nums.index(target)
二分法:
和旋转数组寻找最小值不一样,只要判断middle和left,right的大小即可。这要分成多种情况讨论。旋转点在middle右侧和旋转点在middle左侧,然后又分为两种情况。
class Solution:
# @param {integer[]} numss
# @param {integer} target
# @return {integer}
def search(self, nums, target):
if not nums:
return -1
low, high = 0, len(nums) - 1
while low <= high:
mid = (low + high) >> 1
if target == nums[mid]:
return mid
if nums[low] <= nums[mid]:
if nums[low] <= target <= nums[mid]:
high = mid - 1
else:
low = mid + 1
else:
if nums[mid] <= target <= nums[high]:
low = mid + 1
else:
high = mid - 1
return -1
def search(self, nums, target):
lo, hi = 0, len(nums) - 1
while lo < hi:
mid = (lo + hi) / 2
if (nums[0] > target) ^ (nums[0] > nums[mid]) ^ (target > nums[mid]):
lo = mid + 1
else:
hi = mid
return lo if target in nums[lo:lo+1] else -1
34.Find First and Last Position of Element in Sorted Array
暴力做法,找到所有满足条件的数字,然后求index的最大最小值
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
result = [index for index,item in enumerate(nums) if item == target]
if len(result) == 0:
result = [-1, -1]
return [min(result),max(result)]
双指针,在整个list范围,建立两个指针,从两头开始遍历:
# 108ms
# 12.9MB
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if nums == []:
return [-1,-1]
left,right = 0,len(nums)-1
while nums[left] != target or nums[right]!=target:
if nums[left] != target:
left += 1
if nums[right] != target:
right -= 1
if left > right:
return [-1,-1]
return [left,right]
先找第一个和target相等的点(通过遍历来寻找),然后找最后一个和target相等点:
# 40ms
# 13.8MB
class Solution(object):
def searchRange(self, nums, target):
first, last = 0, 0
i, j = 0, 0
for i in range(len(nums)):
if nums[i] == target:
first = i
break
else:
return [-1, -1]
for j in range(i+1, len(nums)):
if nums[j] != target:
last = nums[j-1]
return [i, j-1]
else:
return [i, j or i]
分别查找和target相等的第一个点和最后一个点,采用二分查找而不是遍历。
class Solution:
# returns leftmost (or rightmost) index at which `target` should be inserted in sorted
# array `nums` via binary search.
def extreme_insertion_index(self, nums, target, left):
lo = 0
hi = len(nums)
while lo < hi:
mid = (lo + hi) // 2
if nums[mid] > target or (left and target == nums[mid]):
hi = mid
else:
lo = mid+1
return lo
def searchRange(self, nums, target):
left_idx = self.extreme_insertion_index(nums, target, True)
# assert that `left_idx` is within the array bounds and that `target`
# is actually in `nums`.
if left_idx == len(nums) or nums[left_idx] != target:
return [-1, -1]
return [left_idx, self.extreme_insertion_index(nums, target, False)-1]
39.Combination Sum:
知道采用递归,但是依然不太会,懵逼。
class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
candidates = sorted(candidates)
def combine(start,target):
answer=[]
for i in range(start,len(candidates)):
if target<candidates[i]:
break
if target==candidates[i]:
answer.append([target])
break
for item in combine(i,target-candidates[i]):
item.append(candidates[i])
answer.append(item)
return answer
return combine(0,target)
40.组合总和II:
此题不能用循环,因为求和不等于target就不会保存在result里面,后续遍历就获取不到。
42.Trapping Rain Water
暴力:遍历数组,求每个柱子上面能留存的最多的水,也就是
class Solution(object):
# 超时
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
ans = 0
size = len(height)
for i in range(1, size-1):
max_left,max_right = 0,0
for j in range(i, -1, -1):
max_left = max(max_left, height[j])
for j in range(i, size):
max_right = max(max_right, height[j])
ans += min(max_left, max_right) - height[i]
return ans
双指针,left和right两个指针,设left_max和right_max两个标志位。只要height[left]不大于left_max,那么留存的水便是left_max - height[left]。right如是操作。
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
left ,right = 0,len(height)-1
ans = 0
left_max, right_max = 0,0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
ans += left_max - height[left]
left += 1
else:
if height[right] > right_max:
right_max = height[right]
else:
ans += right_max - height[right]
right -= 1
return ans
46.Permutations
生成数组的全排列。采用递归,遍历数组的每一个字符,然后去除这个字符,递归这个函数。
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if nums is None: return []
if len(nums) == 1: return [nums]
res = []
for x in nums:
ys=nums+[]
ys.remove(x)
for y in self.permute(ys):
res.append([x]+y)
return res
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
ans = []
if len(nums) == 0:
return
if len(nums) == 1:
return [nums]
for index,item in enumerate(nums):
res = nums[:index]+nums[index+1:] #剩余的数字集合
for j in self.permute(res): #对剩余的数字进行递归
ans.append(j+[item])
return ans
48.Rotate Image
旋转90°相当于首先对矩阵进行reverse然后进行转置。
class Solution:
def rotate(self, A):
A.reverse()
for i in range(len(A)):
for j in range(i):
A[i][j], A[j][i] = A[j][i], A[i][j]
非常精彩的代码,一行结束。和上面做法是一样的,但是语法更简洁。
class Solution:
def rotate(self, A):
A[:] = map(list, zip(*A[::-1]))
49. Group Anagrams
建立一个Hash表,key是每个string排序后的结果,value是一个list保存key相同的string。
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
result = {}
for str1 in strs:
try:
result[''.join(sorted(str1))] += [str1]
except:
result[''.join(sorted(str1))] = [str1]
return list(result.values())
# 与上面的方法一样,但是采用collections类
class Solution(object):
def groupAnagrams(self, strs):
ans = collections.defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
53.Maximum Subarray
遍历所有子序列,然后求和比较最大值。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
max_sum = -1e10
length = len(nums)
for i in range(length):
for j in range(i+1, length+1):
temp = sum(nums[i:j])
if temp > max_sum:
max_sum = temp
return max_sum
遍历依次数组,比较从前面某一点开始到当前值的求和和当前值的大小。保证到当前值的子序列都是最大的。
class Solution:
# @param A, a list of integers
# @return an integer
# 6:57
def maxSubArray(self, A):
if not A:
return 0
curSum = maxSum = A[0]
for num in A[1:]:
curSum = max(num, curSum + num)
maxSum = max(maxSum, curSum)
return maxSum
55. Jump Game:
采用贪心,从最后一个值出发,向前找第一个能到达这个有效值的点。依次判断每个点是否是一个有效点,称为Good Position,否则为Bad Position。判断最后一个有效点是否是零点。
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
length = len(nums)
lastPos = length - 1
for i in range(length-1, -1,-1):
if nums[i] + i >= lastPos:
lastPos = i
return lastPos == 0
56. Merge Intervals
首先根据第一个字符对其进行排序,然后判断每个区间的end值是否大于下一个区间的start值,如果大于等于则进行合并。否则直接拼接在result里面即可。
def merge(intervals):
"""
:type intervals: List[Interval]
:rtype: List[Interval]
"""
# 执行用时 : 96 ms
# 内存消耗 : 16.4 MB
intervals = sorted(intervals, key=lambda x:x[0])
result = []
for list1 in intervals:
# result为空则
if not result or result[-1][1] < list1[0]:
result.append(list1)
else:
result[-1][1] = list1[1]
return result
62. Unique Paths
一个非常秀的做法。从起始点到终点,一共m+n-2步,其中m-1步向下,n-1步向左。所以可以认为是个组合问题,从m+n-2步中选择m-1步作为向下的,也就是 。
class Solution(object):
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
return math.factorial(m+n-2)/math.factorial(m-1)/math.factorial(n-1)
动态规划,软肋,始终无法真正弄懂DP
class Solution(object):
def uniquePaths(self, m, n):
table = [[0 for x in range(n)] for x in range(m)]
for i in range(m):
table[i][0] = 1
for i in range(n):
table[0][i] = 1
for i in range(1,m):
for j in range(1,n):
table[i][j] = table[i-1][j] + table[i][j-1]
return table[m-1][n-1]
64. Minimum Path Sum
动态规划求解,2333,贼烦。
class Solution(object):
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
table = [[0 for x in range(n)] for x in range(m)]
for i in range(m):
table[i][0] = 1
for i in range(n):
table[0][i] = 1
for i in range(1,m):
for j in range(1,n):
table[i][j] = table[i-1][j] + table[i][j-1]
return table[m-1][n-1]
70. Climbing Stairs
斐波那契数列问题。
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n == 1:
return 1
if n == 2:
return 2
m1 = 1
m2 = 2
for i in range(2,n):
temp = m2
m2 = m2 + m1
m1 = temp
return m2
72. Edit Distance
编辑距离
class Solution(object):
# O(m*n) space
def minDistance(self, word1, word2):
l1, l2 = len(word1)+1, len(word2)+1
dp = [[0 for _ in xrange(l2)] for _ in xrange(l1)]
for i in xrange(l1):
dp[i][0] = i
for j in xrange(l2):
dp[0][j] = j
for i in xrange(1, l1):
for j in xrange(1, l2):
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+(word1[i-1]!=word2[j-1]))
return dp[-1][-1]
75. Sort Colors
其实就是对列表进行排序
# 36ms
# 11.6Mb
class Solution(object):
def sortColors(self, nums):
nums.sort()
遍历一次list,遇到0就把他插入到list的第一个位置,遇到2就把他插入到list的最后位置
# 32ms
# 11.7Mb
class Solution(object):
def sortColors(self,nums):
n = len(nums)
index = 0
index2 = 0
while index < n-index2:
if nums[index]==0:
nums.pop(index)
nums.insert(0,0)
index += 1
elif nums[index]==2:
nums.pop(index)
nums.append(2)
index2 += 1
else:
index += 1
76. Minimum Window Substring
from collections import Counter
class Solution(object):
def minWindow(self,s ,t):
# 建立一个字典,保存每个字符出现的次数
dict_t = Counter(t)
# 需要满足的次数,即非重复的字符数
required = len(dict_t)
# 记录当前窗口满足的条件数,
formed = 0
left, right = 0,0
# ans是一个tuple,记录字符串子字符串长度和起始点
ans = float('inf'),0,0
# 当前窗口的字符的频率的统计
window_count = {}
while right < len(s):
char = s[right]
window_count[char] = window_count.get(char,0) + 1
# 如果满足以下条件,满足的条件数即加1
if char in window_count and window_count[char] == dict_t[char]:
formed += 1
# 如果条件均满足那么缩减窗口大小
while left <= right and formed == required:
char = s[left]
# 替换窗口长度,取最小值
if right - left + 1 < ans[0]:
ans = right - left + 1,left,right
window_count[char] -= 1
# 如果去掉一个字符后,依然满足条件,继续进行,如果不满足条件将formed-1
if char in dict_t and window_count[char] < dict_t[char]:
formed -= 1
left += 1
right += 1
return "" if ans[0] == float("inf") else s[ans[1] : ans[2] + 1]
78. 子集
循环: 遍历nums,然后遍历result,将reuslt的每一个list和nums里面的元素做拼接。nums每增加一个新元素,都对result中的元素进行拼接,然后和初始的result拼接在一起。
def subsets(self, nums):
# 36ms
# 11.7Mb
result = [[]]
for num in nums:
result += [item + [num] for item in result]
return result
DFS:
class Solution(object):
def subsets(self, nums):
res = []
self.dfs(sorted(nums), 0, [], res)
return res
def dfs(self, nums, start, path, res):
res.append(path)
for i in range(start, len(nums)):
self.dfs(nums, i+1, path+[nums[i]], res)
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
self.result = []
self.generate(nums,[],0)
return self.result
def generate(self,nums,item,index):
if index == len(nums):
self.result.append(item)
return
self.generate(nums, item+[nums[index]], index+1)
self.generate(nums, item, index+1)
84. Largest Rectangle in Histogram
暴力法求所有的子间隔的面积,然后求最大值。
def largestRectangleArea(self, heights):
"""
:type heights: List[int]
:rtype: int
"""
length = len(heights)
left,right = 0,length
maxarea = 0
for i in range(length):
for j in range(i+1, length+1):
area = min(heights[i:j]) * (j-i)
maxarea = max(area, maxarea)
return maxarea
依然看不太懂,思路明白但是实现方式不太懂,对于栈的一些知识不太了解。
https://blog.csdn.net/Zolewit/article/details/88863970
def largestRectangleArea(self, height):
height.append(0)
stack = [-1]
ans = 0
for i in xrange(len(height)):
while height[i] < height[stack[-1]]:
h = height[stack.pop()]
w = i - stack[-1] - 1
ans = max(ans, h * w)
stack.append(i)
height.pop()
return ans
90.子集II:
循环: 和78题类似,只不过在增加新的子集的时候判断是否在已知的里面,这可以解决同序重复问题([1,2,2],[1,2,2])。排序后可以解决不同序重复问题([1,2,2],[2,1,2])。
class Solution(object):
def subsetsWithDup(self, nums):
result = [[]]
for num in sorted(nums):
result += [i+[num] for i in result if i+[num] not in result]
return result
94. Binary Tree Inorder Traversal
递归方法实现:
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ans=[]
if root==None:
return ans
def dfs(root):
if root==None:
return
dfs(root.left)
ans.append(root.val)
dfs(root.right)
return
dfs(root)
return ans
非递归方法:
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
#非递归方法
stack=[]
ans=[]
while(root or stack):
while(root):
stack.append(root)
root=root.left
root=stack.pop()
ans.append(root.val)
root=root.right
return ans
102. 二叉树的层次遍历:
用queue依次保存树的结点,向下遍历,依次保存每层的结点。每次遍历一次queue,相当于遍历依次上一层的所有结点,遍历一个结点便取出一个结点,直到queue为空为止。
class Solution(object):
def levelOrder(self, root):
if root is None:
return
queue=[root]
res=[]
while queue:
tem=[]
for i in range(len(queue)):
cur_node = queue.pop(0)
tem.append(cur_node.val)
if cur_node.left is not None:
queue.append(cur_node.left)
if cur_node.right is not None:
queue.append(cur_node.right)
res.append(tem)
return res
104.二叉树的最大深度:
递归,寻找递归关系。如果根节点不为空,那么返回两颗子树最大深度的最大值然后加1.
class Solution(object):
def maxDepth(self, root):
if root == None:
return 0
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
111. 二叉树的最小深度:
利用递归,如果根节点为空那么返回o。如果左右子树一个为空,返回另一个子树的mindepth同时+1.如果左右子树均不为空,则返回两棵树min(mindepth1, mindepth2) + 1
。
class Solution:
# @param root, a tree node
# @return an integer
def minDepth(self, root):
if root == None:
return 0
if root.left==None or root.right==None:
return self.minDepth(root.left)+self.minDepth(root.right)+1
return min(self.minDepth(root.right),self.minDepth(root.left))+1
121.Best Time to Buy and Sell Stock:
使用暴力法进行遍历,后面的和前面比。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
max_sum = 0
length = len(prices)
for i in range(length-1):
for j in range(i+1, length):
max_sum = max(max_sum, prices[j]-prices[i])
return max_sum
遍历依次列表,保存一直到当前数值,遇到的最小值,用遍历的值减去最小值,求最大。相当于求每个值和前面最小值的差(这个值通过遍历依次保存),然后求这个差的最大值。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
maxsum = 0
length = len(prices)
minprice = 1e10
for num in prices:
if num < minprice:
minprice = num
maxsum = max(maxsum, num-minprice)
return maxsum
122. Best Time to Buy and Sell Stock II
暴力法,太复杂。
一次遍历,我们应该保存每一次相邻的波峰和波谷,多个相邻的波峰和波谷的差求和,要大于最优的选择(上题的最优解)。最极端的例子是12345类似的连续的序列,多个波峰波谷求和和最优单解相同。
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if prices == []:
return 0
i,valley,peak = 0,prices[0],prices[0]
maxprofit = 0
length = len(prices)
while i < length -1:
# 如果当前值大于下一个值就一直往前走,找波谷
while i < length - 1 and prices[i] >= prices[i+1]:
i += 1
valley = prices[i]
# 如果当前值小于下一个值就一直走,找波峰
while i < length - 1 and prices[i] <= prices[i+1]:
i += 1
peak = prices[i]
maxprofit += peak - valley
print(maxprofit)
return maxprofit
128. Longest Consecutive Sequence
暴力法,排序后然后依次遍历。注意边界情况nums为空。注意去重,存在重复值排序后会存在bug。
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 0:
return 0
nums = sorted(set(nums))
maxlen = 1
temp = 1
for i in range(len(nums)-1):
if nums[i+1] - nums[i] == 1:
temp += 1
else:
temp = 1
maxlen = max(temp, maxlen)
return maxlen
将序列保存成一个set(python的查找复杂度是 ),找到连续序列开头的第一个值,然后依次判断后面的值是否在nums里面。
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
maxlen = 0
nums = set(nums)
for num in nums:
# 找到连续序列开头的第一个值
if num-1 not in nums:
cur_num = num
cur_len = 1
# 求后面序列的长度,这一步判断是O(1)
while cur_num + 1 in nums:
cur_num += 1
cur_len += 1
maxlen = max(maxlen, cur_len)
return maxlen
136.Single Number
哈希表
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
num_count = {}
for num in nums:
num_count[num] = num_count.get(num,0) + 1
for key,value in num_count.items():
if value == 1:
return key
141. Linked List Cycle
判断链表中是否有环,将链表中的元素设为某个奇葩值,如果链表元素会等于这个奇葩值,那么就是有环。
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
while head:
if head.val == 'like':
return True
else:
head.val = 'like'
head = head.next
return False
快慢指针,建立两个指针,快指针和慢指针,快指针在前面,如果快指针后来超过了慢指针那么就是有环的。否则没有。
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head == None or head.next == None:
return False
slow = head
fast = head.next
while slow != fast:
if fast == None or fast.next == None:
return False
slow = slow.next
fast = fast.next.next
return True
142. Linked List Cycle II
建立一个哈希表保存链表中已经出现的结点,如果结点出现重复则判定为循环节。2333字典的查找速度要快于set????
class Solution(object):
# 60ms
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
unique_dict = {}
while head:
if head in unique_dict:
return head
unique_dict[head] = ''
head = head.next
class Solution(object):
# 64ms
def detectCycle(self, head):
head_set = set()
while head:
if head in head_set:
return head
else:
head_set.add(head)
head = head.next
方法二:详细解释 + python实现
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
try:
fast = head.next.next
slow = head.next
while fast != slow:
slow = slow.next
fast = fast.next.next
except:
return None
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow
152.Maximum Product Subarray
暴力法:
class Solution(object):
def maxProduct(self, nums):
maxProd = -1e10
for i in range(len(nums)):
for j in range(i+1, len(nums)+1):
temp = 1
for k in range(i,j):
temp *= nums[k]
maxProd = max(maxProd, temp)
return maxProd
从前到后遍历,依次乘积的结果保存在list中相应的位置,主要解决的是0和负数的问题。最大值的情况,一定是从两头开始的,所以需要两头都需要考虑。
class Solution(object):
def maxProduct(self, A):
"""
:type nums: List[int]
:rtype: int
"""
B = A[::-1]
for i in range(1,len(A)):
A[i] *= A[i-1] or 1
B[i] *= B[i-1] or 1
return max(max(A),max(B))
155.Min Stack
求得栈的最小值,时间复杂度是O(1) O(1)O(1)。建立一个辅助栈,每增加一个数,保存目前所有数的最小值在辅助栈的栈顶。
注意:辅助栈(minStack)何时入栈,出栈的时候注意边界值。
class MinStack(object):
# 运行时间:23ms
# 占用内存:5752k
def __init__(self):
self.stack = []
self.minStack = []
def push(self, node):
# write code here
self.stack.append(node)
if self.minStack == [] or node < self.getMin():
self.minStack.append(node)
else:
temp = self.getMin()
self.minStack.append(temp)
def pop(self):
# write code here
if self.stack == None or self.minStack == None:
return None
self.minStack.pop()
self.stack.pop()
def top(self):
# write code here
return self.stack[-1]
def getMin(self):
# write code here
return self.minStack[-1]
160.Intersection of Two Linked Lists
直到两个相等,否则一直遍历。
class Solution:
def getIntersectionNode(self, headA, headB):
if headA is None or headB is None:
return None
pa = headA # 2 pointers
pb = headB
while pa is not pb:
# if either pointer hits the end, switch head and continue the second traversal,
# if not hit the end, just move on to next
pa = headB if pa is None else pa.next
pb = headA if pb is None else pb.next
return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None
169.求众数:
哈希表直接求即可。
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
num_count = {}
for num in nums:
num_count[num] = num_count.get(num,0) + 1
length = len(nums)//2
for key,value in num_count.items():
if value > length:
return key
return -1
198.打家劫舍:
采用递归求解,判断好结束条件,然后写递推公式即可,但是超时。
class Solution(object):
def rob(self, nums):
if len(nums) == 0:
return 0
if len(nums) <= 2:
return max(nums)
num2 = nums[1]
num1 = nums[0] + self.rob(nums[2:])
if len(nums) >= 4:
num2 += self.rob(nums[3:])
return max(num1, num2)
采用动态规划,依然不是很懂,解法.
class Solution:
# @param num, a list of integer
# @return an integer
def rob(self, num):
max_3_house_before, max_2_house_before, adjacent = 0, 0, 0
for cur in num:
max_3_house_before, max_2_house_before, adjacent = \
max_2_house_before, adjacent, max(max_3_house_before+cur, max_2_house_before+cur)
return max(max_2_house_before, adjacent)
200. 岛屿的个数:
class Solution():
def numIslands(self, grid):
def sink(i, j):
if 0 <= i < len(grid) and 0 <= j < len(grid[i]) and grid[i][j] == '1':
grid[i][j] = '0'
map(sink, (i+1, i-1, i, i), (j, j, j+1, j-1))
return 1
return 0
return sum(sink(i, j) for i in range(len(grid)) for j in range(len(grid[i])))
206.反转链表:
原链表的的第一个值的next必然是None,所以首先设一个链表为None(返回的答案)。然后依次遍历head,将head保存在prev里面,同时将prev的next指向prev,利用了python能同时赋值的特性,不必再设置别的变量来保存prev。这是最简单的写法,分开写比较麻烦。
class Solution(object):
def reverseList(self, head):
prev = None
while head:
prev,prev.next,head = head,prev,head.next
return prev
分开写:
class Solution(object):
def reverseList(self, head):
prev = None
while head:
temp = head.next
head.next = prev
prev = head
head = temp
return prev
208.实现前缀树:
直接实现即可,建立一个list,然后完成相应的功能。
class Trie(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.trie =[]
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: None
"""
self.trie.insert(0,word)
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
if word in self.trie:
return True
else:
return False
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
length = len(prefix)
flag = False
for strings in self.trie:
if prefix == strings[:length]:
flag = True
return flag
215.数组中的第k个最大元素
作弊操作,调用内部函数。应该自己写快排尝试解决。
class Solution(object):
# 72 ms
# 12.2Mb
def findKthLargest(self, nums, k):
return sorted(nums)[-k]
222.完全二叉树的节点:
利用递归,只要建立好递推关系式和终止条件,其他都好说。
class Solution(object):
def countNodes(self, root):
if root == None:return 0
return self.countNodes(root.left) + self.countNodes(root.right) + 1
226.翻转二叉树
通过递归来实现,对左子树和右子树执行相同的操作,然后交换左右子树。
class Solution(object):
# 32 ms
# 11.8Mb
def invertTree(self, root):
if root == None:
return None
if root.left != None:
root.left = self.invertTree(root.left)
if root.right != None:
root.right = self.invertTree(root.right)
root.right,root.left = root.left,root.right
return root
232.用栈实现队列:
2333直接用list实现的,貌似作弊?
class MyQueue(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.queue = []
def push(self, x):
"""
Push element x to the back of queue.
:type x: int
:rtype: None
"""
self.queue.append(x)
def pop(self):
"""
Removes the element from in front of queue and returns that element.
:rtype: int
"""
return self.queue.pop(0)
def peek(self):
"""
Get the front element.
:rtype: int
"""
return self.queue[0]
def empty(self):
"""
Returns whether the queue is empty.
:rtype: bool
"""
return self.queue == []
234.回文链表:
class Solution(object):
# 96 ms
# 31.6Mb
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
list1 = []
while head:
list1.append(head.val)
head = head.next
for i in range(len(list1)//2):
if list1[i] != list1[len(list1)-1-i]:
return False
return True
238.Product of Array Except Self
重点是统计0的个数。没有0,用除法即可。有一个0,那么有一个数不为0,其他均为0。有两个及以上的0,所有都是0.
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
zeroNum = 0
product = 1
for num in nums:
if num == 0:
zeroNum += 1
else:
product *= num
for i in range(len(nums)):
if nums[i] == 0 and zeroNum == 1:
nums[i] = product
elif zeroNum == 0:
nums[i] = product/nums[i]
else:
nums[i] = 0
return nums
little trick,从左到右遍历,保存每个数前面所有的数的乘积。从右到左遍历,相当于保存这个数后面所有数的乘积。所有遍历两次数组,即可求出当前这个数前面所有数和后面所有数的乘积。
class Solution:
# @param {integer[]} nums
# @return {integer[]}
def productExceptSelf(self, nums):
p = 1
n = len(nums)
output = []
for i in range(n):
output.append(p)
p = p * nums[i]
p = 1
for i in range(n-1,-1,-1):
output[i] = output[i] * p
p = p * nums[i]
return output
239.滑动窗口最大值
遍历即可,时间复杂度是 。
class Solution(object):
def maxSlidingWindow(self, nums, k):
if len(nums) == 0 or k == 0:
return []
result = []
for i in range(len(nums) - k+1):
result.append(max(nums[i:i+k]))
return result
240.搜索二维矩阵 II:
暴力法直接遍历:
class Solution(object):
def searchMatrix(self, matrix, target):
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] == target:
return True
return False
矩阵是每行的元素从左到右升序排列。每列的元素从上到下升序排列。所以可以从右上到左下遍历,如果matrix[i][j]小于这个target,那么i加1,大于target则j减1。
class Solution(object):
# 76 ms 62.66%
# 15.7Mb
def searchMatrix(self, matrix, target):
if len(matrix) == 0 or len(matrix[0]) == 0:
return False
i,j = 0,len(matrix[0])-1
while i < len(matrix) and j >= 0:
if matrix[i][j] == target:
return True
elif matrix[i][j] < target:
i += 1
elif matrix[i][j] > target:
j -= 1
return False
284.移动零:
遍历遇到0就remove,然后在末尾添新的0。
class Solution(object):
def moveZeroes(self, nums):
for num in nums:
if num == 0:
nums.remove(0)
nums.append(0)
return nums
287.寻找重复数
排序,然后判断两个相邻的数是否相等,如果相等那么是重复的: 。空间复杂度0.
class Solution:
def findDuplicate(self, nums):
nums.sort()
for i in range(1, len(nums)):
if nums[i] == nums[i-1]:
return nums[i]
哈希表保存次数: ,空间复杂度较高。
class Solution(object):
# 84ms 38.32%
# 14.9Mb 5.09%
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
count = {}
for num in nums:
count[num] = count.get(num,0) + 1
for num in nums:
if count[num] > 1:
return num
return None
采用set保存已经出现过的数,比上一种更快。
def findDuplicate(self, nums):
seen = set()
for num in nums:
if num in seen:
return num
seen.add(num)
409.Longest Palindrome
统计字符串中每个字符的出现的次数,如果次数为偶数,直接相加,奇数除以2取整。count/2*2
# 28ms
# 11.6Mb
class Solution:
def longestPalindrome(self, s):
ans = 0
for v in collections.Counter(s).values():
ans += int(v / 2) * 2
if ans & 1 == 0 and v & 1 == 1:
ans += 1
return ans
438. 找到字符串中所有字母异位词
暴力做法,遍历所有字符串
class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
result = []
len_p = len(p)
for i in range(len(s)-len_p+1):
if sorted(s[i:i+len_p]) == sorted(p):
result.append(i)
return result
448.找到所有数组中消失的数字:
保存完整数组,然后遍历。
class Solution(object):
# 464 ms,73.91%
def findDisappearedNumbers(self, nums):
result = []
nums2 = list(range(1,len(nums)+1))
nums = set(nums)
return [num for num in nums2 if num not in nums]
461.汉明距离:
异或然后求其二进制中1的个数直接判断。
class Solution(object):
def hammingDistance(self, x, y):
result = x^y
count = 0
for i in str(bin(result)):
if i == '1':
count += 1
return count
494. 目标和
DFS
581.最短无序连续子数组:
对原数组进行排序,比较排好序的数组和原数组的差别,第一位不同的便是最短无序子数组的头;倒序遍历,第一个不同的便是尾。
class Solution(object):
# 264ms 32.54%
def findUnsortedSubarray(self, nums):
nums2 = sorted(nums)
for i in range(len(nums)):
if nums[i] != nums2[i]:
start = i
break
for i in range(len(nums)-1, -1,-1):
if nums[i] != nums2[i]:
end = i
break
try:
return end-start+1
except:
return 0
617.合并二叉树:
采用递归,将第二颗二叉树额值依次加到第一棵树上面,如果某一个棵树为None则返回另一颗树。确定根节点后,依次再向下考虑左右叶子结点。
class Solution(object):
# 84 ms # 59.6%
def mergeTrees(self, t1, t2):
if t1 == None:
return t2
if t2 == None:
return t1
t1.val += t2.val
t1.left = self.mergeTrees(t1.left, t2.left)
t1.right = self.mergeTrees(t1.right, t2.right)
return t1
647. Palindromic Substrings
暴力做法,确定每一个子字符串是否是回文字符串,然后统计个数
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
count = 0
def IsPalin(strs):
# 判断一个字符串是否是回文字符串,头和尾比较
for i in range(int(len(strs)/2)):
if strs[i] != strs[-i-1]:
return False
return True
def IsPalin2(strs):
# 判断是否是回文,翻转字符串判断是否相等
if strs[::-1] == strs:
return True
return False
for i in range(len(s)):
for j in range(i+1, len(s)+1):
if IsPalin(s[i:j]):
count += 1
return count
遍历字符串,以每个字符为中心,向两边展开,判断每个新加入的字母是否相等。
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
count = 0
for i in range(len(s)):
start,end = i,i
while(start >= 0 and end < len(s) and s[start] == s[end]):
start -= 1
end += 1
count += 1
start,end = i,i+1
while(start >= 0 and end < len(s) and s[start] == s[end]):
start -= 1
end += 1
count += 1
return count
771. Jewels and Stones
class Solution(object):
def numJewelsInStones(self, J, S):
"""
:type J: str
:type S: str
:rtype: int
"""
return sum([1 if i in J else 0 for i in S])