写在前面
近半个月的整理, 终于完成了前一百题的easy和medium题目的分析 😅 秋招已经开始了, 祝自己好运 😇 以后有空逐渐把hard补上 😎
文章目录
- 2. Add Two Numbers (Medium)
- 3. Longest Substring Without Repeating Characters (Medium)
- 5. Longest Palindromic Substring (Medium)
- 6. ZigZag Conversion (Medium)
- 8. String to Integer (atoi) (Medium)
- 11. Container With Most Water (Medium)
- 12. Integer to Roman (Medium)
- 15. 3Sum (Medium) **
- 16. 3Sum Closest (Medium)
- 17. Letter Combinations of a Phone Number (Medium)
- 18. 4Sum (Medium)
- 19. Remove Nth Node From End of List (Medium)
- 22. Generate Parentheses (Medium)
- 24. Swap Nodes in Pairs (Medium)
- 29. Divide Two Integers (Medium) X
- 31. Next Permutation (Medium)
- 33. Search in Rotated Sorted Array (Medium)
- 81. Search in Rotated Sorted Array II (Medium)
- 34. Find First and Last Position of Element in Sorted Array (Medium)
- 36. Valid Sudoku (Medium)
- 39. Combination Sum (Medium)
- 40. Combination Sum II (Medium)
- 42. Trapping Rain Water (Hard)
- 43. Multiply Strings (Medium)
- 46. Permutations (Medium)
- 47. Permutations II (Medium)
- 48. Rotate Image (Medium)
- 49. Group Anagrams (Medium)
- 54. Spiral Matrix (Medium)
- 59. Spiral Matrix II (Medium)
- 55. Jump Game (Medium)
- 56. Merge Intervals (Medium)
- 60. Permutation Sequence (Medium)
- 61. Rotate List (Medium)
- 62. Unique Paths (Medium)
- 63. Unique Paths II (Medium)
- 64. Minimum Path Sum (Medium)
- 71. Simplify Path (Medium)
- 73. Set Matrix Zeroes (Medium)
- 74. Search a 2D Matrix (Medium)
- 77. Combinations (Medium)
- 78. Subsets (Medium)
- 90. Subsets II (Medium)
- 79. Word Search (Medium)
- 80. Remove Duplicates from Sorted Array II (Medium)
- 82. Remove Duplicates from Sorted List II (Medium)
- 86. Partition List (Medium)
- 89. Gray Code (Medium)
- 91. Decode Ways (Medium) **
- 92. Reverse Linked List II (Medium)
- 93. Restore IP Addresses (Medium)
- 94. Binary Tree Inorder Traversal (Medium)
- 96. Unique Binary Search Trees (Medium)
- 95. Unique Binary Search Trees II (Medium)
- 98. Validate Binary Search Tree (Medium)
2. Add Two Numbers (Medium)
题目描述
给两个链表, 做加法
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
解题思路
"""
类似于合并两个链表
1. 依顺序把l2的元素加到l1中
2. 当一个链表已经加完, 接下来做的就是把进位和剩下的链表加和
3. 当两个链表长度相等, 要判断最后一个节点值是否大于10, 可能产生进位值
4. 当遍历完所有节点后, 如果仍有进位值, 则加入一个新节点
"""
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
head = l1
carry = 0
while l1 or l2:
if l1 and l2:
s = l1.val + l2.val + carry
l1.val = s%10
carry = s//10
last = l1 # 如果l1为空, 把最后一个node指l2
l1 = l1.next
l2 = l2.next
elif l1: # l1比l2长
s = l1.val + carry # 补全进位
l1.val = s%10
carry = s//10
if carry == 0: # 如果不再有进位, 提前终止加和.
break
last = l1
l1 = l1.next
elif l2: # l1比l2短
last.next = l2
s = l2.val + carry
l2.val = s%10
carry = s//10
if carry == 0:
break
last = l2
l2 = l2.next
if last.val >= 10:
last.val = last.val % 10
carry = 1
if carry: #如果carry有值需要加入一个新节点.
last.next = ListNode(1)
return head
3. Longest Substring Without Repeating Characters (Medium)
https://leetcode.com/problems/longest-substring-without-repeating-characters/
题目描述
给一个字符串, 返回最长的没有重复元素的子串.
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
解题思路
"""
设置一个滑动窗口.
每次右边界滑动一个位置, check左边界是否会重复, 如果重复了, 左边界向右滑动, 直到左边界的字符不等于右边界位置上的字符未知.
每次移动结束后, check当前窗口长度.
"""
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if s == '':
return 0
start = end = result = 0
while end < len(s):
if s[end] not in s[start:end]:
end += 1
result = max(result, end-start)
else:
start = start + s[start:end].find(s[end]) + 1 #return the index of s[end] in s[start:end]
end += 1
return result
5. Longest Palindromic Substring (Medium)
题目描述
给一个字符串, 找到最长的回文子字符串.
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
解题思路
"""
遍历所有节点.
1. 从当前节点, 向两边遍历, 直到元素不相等为止. 得到一个回文字符串.
2. check当前回文字符串
注意原字符串的奇偶长度
"""
class Solution:
def longestPalindrome(self, s: str) -> str:
Max = 0
longest = ''
for i in range(len(s)):
#odd case, like'aba'
subStr = self.helper(s, i, i)
if len(subStr) >= Max:
Max = len(subStr)
longest = subStr
#even case, like'abba'
subStr = self.helper(s, i, i+1)
if len(subStr) >= Max:
Max = len(subStr)
longest = subStr
return longest
def helper(self, s, start, end):
subStr = ''
while start >= 0 and end <len(s) and s[start] == s[end]:
subStr = s[start:end+1]
start -= 1
end += 1
return subStr
6. ZigZag Conversion (Medium)
题目描述
字符串 “PAYPALISHIRING"以Z形走法书写, 逐行输出结果为"PAHNAPLSIIGYIR”
P A H N
A P L S I I G
Y I R
设计转换函数.
解题思路
# 倒着的Z字拼接在一起,先找组成Z字的规律
'''
(* *) 虽然是z型看起来复杂,其实简单,走势符合直下斜上的顺序
* * * 创建五个存储空间来保存每次走过的字母即可。
* * *
* * *
* *
'''
class Solution:
def convert(self, s: str, numRows: int) -> str:
# 特殊情况,字符只够摆第一竖列
if numRows == 1 or numRows >= len(s):
return s
L = [''] * numRows
index = 0
# step往下走,当step=-1即回头,往上走
for x in s:
L[index] += x
if index == 0: step = 1
if index == numRows - 1: step = -1
index += step
return ''.join(L)
8. String to Integer (atoi) (Medium)
https://leetcode.com/problems/string-to-integer-atoi/
题目描述
解题思路
class Solution:
def myAtoi(self, s: str) -> int:
if s == '':
return 0
# 将字符串去掉空格保存在列表中,只要研究列表第一个元素即可
s2 = s.strip().split(' ')[0]
# 仍然需要判断一次,不然报错
if s2 == '':
return 0
flag = 1
num = {
'1','2','3','4','5','6','7','8','9','0'}
#保存符号
if s2[0] == '-':
flag = -1
s2 = s2[1:]
elif s2[0] == '+':
s2 = s2[1:]
# 临界判断, 太重要了!单独一个字符'+'或'-'
if s2 == '':
return 0
# 首字符是字母返回0
if s2[0] not in num:
return 0
# 后面如果跟字母要想办法去掉
for i in s2:
if i not in num:
index = s2.index(i)
s2 = s2[:index]
break
s2 = flag * int(s2)
if s2 > 2**31 - 1:
return 2**31 - 1
elif s2 < -(2**31):
return -(2**31)
return s2
11. Container With Most Water (Medium)
https://leetcode.com/problems/container-with-most-water/
题目描述
给一个数组, 每个数字代表隔板长度, 确定能容纳水的最大体积.
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
解题思路
"""
短的隔板决定容器的高度.
设置两个指针, 分别从头尾向中间移动.
1.如果头指针大于尾指针, 则尾指针向头部移动.
2.如果头指针小于尾指针, 则头指针向尾部移动.
3.每次移动完, check当前容积.
"""
class Solution:
def maxArea(self, height: List[int]) -> int:
result = 0
start = 0
end = len(height)-1
while start < end:
result = max(result, min(height[start], height[end]) * (end - start))
#将两条线往对方方向走。
if height[start] < height[end]:
start += 1
else:
end -= 1
return result
12. Integer to Roman (Medium)
https://leetcode.com/problems/integer-to-roman/
题目描述
把罗马数字转换成十进制数字.
解题思路
class Solution:
def intToRoman(self, num: int) -> str:
value_roman = {
1000:"M", 900:"CM", 500:"D", 400:"CD",
100:"C", 90:"XC", 50:"L", 40:"XL",
10:"X", 9:"IX", 5:"V", 4:"IV", 1:"I"}
roman = ""
for v in [1000,900,500,400,100,90,50,40,10,9,5,4,1]:
roman += value_roman[v] * (num//v)
num %= v
return roman
15. 3Sum (Medium) **
https://leetcode.com/problems/3sum/
题目描述
给定一个数组, 找到有所能使得和为0的组合. 组合不能重复.
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[ [-1, 0, 1], [-1, -1, 2] ]
解题思路
"""
动态规划
先将数组排序.
从头开始逐个元素遍历, 位置为i, 左指针指向i+1, 右指针指向tail.
当 左指针 < 右指针 时:
1. 加和三个指针指向的值.
2. 和大于0, 说明和需要减小, 右指针左移一个位置(因为数组有序, 右边数大于左边)
3. 和小于0, 说明和需要增大. 左指针右移一个位置
4. 当和等于0时, 继续移动左右指针去掉与当前值相同的元素
"""
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
if len(nums) <3: # deal with special input
return []
elif len(nums) == 3:
if sum(nums) == 0:
return [sorted(nums)]
res = []
nums.sort()
for i in range(len(nums)-2):
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i+1, len(nums)-1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s < 0:
l +=1
elif s > 0:
r -= 1
else:
res.append((nums[i], nums[l], nums[r]))
while l < r and nums[l] == nums[l+1]:
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
l += 1; r -= 1
return res
16. 3Sum Closest (Medium)
https://leetcode.com/problems/3sum-closest/
题目描述
同上一题, 只是给定一个target, 找出同target最接近的值.
解题思路
"""
同上一题, 三个指针.
"""
class Solution:
def threeSumClosest(self, nums, target):
nums.sort()
res = sum(nums[:3])
for i in range(len(nums)):
l, r = i+1, len(nums)-1
while l < r:
s = sum((nums[i], nums[l], nums[r]))
if abs(s-target) < abs(res-target):
res = s
if s < target:
l += 1
elif s > target:
r -= 1
else: # break early
return res
return res
17. Letter Combinations of a Phone Number (Medium)
https://leetcode.com/problems/letter-combinations-of-a-phone-number/
题目描述
输入数字字符串, 输出可能的字母组合. (九宫格按键)
Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
解题思路
递归
"""
"""
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if digits == "":
return []
mapp = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'}
res = []
self.combinate(digits, mapp, 0, len(digits), '', res)
return res
def combinate(self, s, mapp, n, m, path, res):
if n == m:
res.append(path)
return
for i in mapp[s[n]]:
self.combinate(s, mapp, n+1, m, path+i, res)
非递归做法
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
pad = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
}
if not digits:
return []
output = ['']
for digit in digits:
temp = output
output = []
for s in temp:
output.extend([s + pad[digit][0], s + pad[digit][1], s+ pad[digit][2]])
if digit == '7' or digit == '9':
output.append(s + pad[digit][3])
return output
18. 4Sum (Medium)
https://leetcode.com/problems/4sum/
题目描述
同3Sum, 只是改为四个数和为0.
解题思路
"""
3Sum的拓展
在4Sum中将0-当前数作为target传入3Sum函数
"""
class Solution:
def fourSum(self, nums, target):
results = []
nums.sort()
for i in range(len(nums)-3):
if i == 0 or nums[i] != nums[i-1]:
threeResult = self.threeSum(nums[i+1:], target-nums[i])
for item in threeResult:
results.append([nums[i]] + item)
return results
def threeSum(self, nums, target):
results = []
nums.sort()
for i in range(len(nums)-2):
l = i + 1; r = len(nums