class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
dic = dict()
for i in range(len(nums)):
another_num = target - nums[i]
if another_num in dic:
return [dic[another_num], i]
else:
dic[nums[i]] = i
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 is None:
return l2
if l2 is None:
return l1
# tmp是暂存(temporal)
tmp = ListNode(0) # 引用ListNode类定义了一个链表节点并赋给tmp
# res是重置(reset)
res = tmp # 赋值
# flag 标示
flag = 0 # 初始化
while l1 or l2: # l1或l2不为空就持续执行
tmp_sum = 0 # 链表节点值的和
if l1: # 如果l1不为空,把l1的某个节点值的和赋给tmp_sum
tmp_sum = l1.val # 把l1的某个节点的值赋给tmp_sum
l1 = l1.next
if l2: # 如果l2不为空,把l2中和l1对应的节点的值加到tmp_sum
tmp_sum += l2.val
l2 = l2.next # 指向下一个节点,为下一次的加和做准备
tmp_res = ((tmp_sum + flag) % 10) # 个位数字
flag = ((tmp_sum + flag) // 10) # 进位的数
res.next = ListNode(tmp_res)
res = res.next # res后移
if flag: # 如果flag不为0,就是对应位置相加后有进位
res.next = ListNode(1) # res的下一节点设为1
res = tmp.next # 赋值
del tmp # 删除tmp变量
return res # 返回res链表
3. The longest substring without repeating characters
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
last = {}
start = 0
res = 0
for i in range(len(s)):
if s[i] in last:
start = max(start, last[s[i]] +1)
last[s[i]] = i
res = max(res, last[s[i]]-start+1)
return res
4. Find the median of two ordinal arrays
Median calculation rules:
1. If the length of the sequence is odd, the subscript corresponding to the median is (length / 2) + 1
2. If the length of the sequence is even, the median corresponds to the average of the number subscripted as length / 2 and (length / 2) + 1.
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
nums1.extend(nums2)
nums1.sort()
# 判断合并后列表的长度是奇数还是偶数,然后根据中位数计算规则计算出中位数
length = len(nums1)
if length % 2 == 0:
return (nums1[int(length/2 - 1)] + nums1[int(length/2)]) / 2.0
else:
return nums1[int((length+1)/2 - 1)]
5. Longest Palindromic Substring
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
size=len(s)
max_len=1
start=0
dp=[[False for _ in range(size)] for _ in range(size)]#创建二维数组
for i in range(size):#单位数必然是回文数
dp[i][i]=True
for j in range(1,size):#遍历两位及以上的数组,判定dp[i][j]是否为回文,一旦确定即记录起始位置和长度
for i in range(j):
if s[i]==s[j]:
if j-i<3:#符合边界条件并且两边相等,即return True
dp[i][j]=True
else:
dp[i][j]=dp[i+1][j-1]#没达到边界条件,继续状态转移,判定子集是否达到边界条件
else:
dp[i][j]=False
if dp[i][j]:
cur_len=j-i+1
if cur_len>max_len:
max_len=cur_len#记录最长回文数的长度
start=i#记录起始位置
return s[start:start+max_len]
[Leetcode] Python implements zigzag transformation_HelloWorld-CSDN Blog
class Solution(object):
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
str_length = len(s)
node_length = 2*numRows - 2 # 两列之间的差
result = ""
if str_length == 0 or numRows == 0 or numRows == 1:
return s
for i in range(numRows): # 从第一行遍历到最后一行
for j in range(i, str_length, node_length):
result += s[j] # 第一行和最后一行 还有普通行的整列数字
if i != 0 and i != numRows-1 and j - 2*i + node_length < str_length:
result += s[j-2*i+node_length] # 单列行的数字
return result
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
if x < pow(2,31)*(-1) or x > pow(2,31):
return 0
if x >= 0:
x = int("".join(list(str(x))[::-1]))
else:
x = int("".join(list(str(abs(x)))[::-1])) * (-1)
if x < pow(2,31)*(-1) or x > pow(2,31):
return 0
return x
8. Convert string to integer (atoi) (to be seen)
class Solution(object):
def myAtoi(self, s):
"""
:type s: str
:rtype: int
"""
s = s.strip()
if not s:
return 0
sign = 1
if s[0] == '-':
sign = -1
s = s[1:]
elif s[0]=='+':
s = s[1:]
num = ''
for c in s:
if c.isdigit():
num += c
else:
break
if not num:
return 0
num = int(num)*sign
INT_MAX = 2**31
return min(max(num,-1*INT_MAX), INT_MAX-1)
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
x = list(str(x))
y = x[::-1]
if x == y:
return True
else:
return False
21. Merge two sorted linked lists
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
node = ListNode(None)
new = node
while l1 and l2:
if l1.val > l2.val:
new.next = l2
l2 = l2.next
else:
new.next = l1
l1 = l1.next
new = new.next
if l1:
new.next = l1
if l2:
new.next = l2
return node.next
33. Search a rotated sorted array
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) < 10:
for i in range(len(nums)):
if nums[i] == target:
return i
return -1
left = 0
right = len(nums) - 1
if target >= nums[0]:
while left < right:
if nums[left] > nums[left+1]:
if nums[left] == target:
return left
elif nums[left+1] == target:
return left + 1
else:
return -1
if nums[left] == target:
return left
else:
left+=1
if target <= nums[-1]:
while left < right:
if nums[right] < nums[right-1]:
if nums[right] == target:
return right
elif nums[right+1] == target:
return right + 1
else:
return -1
if nums[right] == target:
return right
else:
right -=1
if target<nums[0] and target>nums[-1]:
return -1
class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
# 结果列表
ans = []
# 可能的组合
tmp = []
def helper(idx, total):
"""回溯,求组合总和
Args:
idx: 选取元素索引
total: 组合中的元素和
"""
# 基准条件
# 当元素和大于目标值,直接返回
if total > target:
return
# 当元素和等于目标值,将组合添加到结果中,返回
if total == target:
ans.append(tmp[::])
return
# 进入分支,同时避免重复组合
for i in range(idx, len(candidates)):
# 更新 total 值,
total += candidates[i]
# 同时将当前元素尝试添加到组合中
tmp.append(candidates[i])
# 再次进入递归
# 这里可以看文章图例,递归向下,可选元素是从自身开始选择
# 这里同时也能避免组合重复,因为不会再次选择索引 i 前面对应的元素
helper(i, total)
# 回溯,回退组合元素及 total 值
tmp.pop()
total -= candidates[i]
total = 0
helper(0, total)
return ans
https://segmentfault.com/a/1190000024416186
class Solution(object):
def combinationSum2(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
candidates.sort()
# 结果列表
ans = []
# 可能组合
tmp = []
def helper(idx, total):
if total == target:
ans.append(tmp[::])
return
if total > target:
return
for i in range(idx, len(candidates)):
# 这里限制同一层不能选择值相同的元素
# 若有相同的元素,优先选择索引靠前的
if candidates[i-1] == candidates[i] and i-1 >= idx:
continue
total += candidates[i]
tmp.append(candidates[i])
# 这里注意,与 39 题不同,进入递归下一层
# 从当前索引的下一位开始选取,避免重复选取同个元素
helper(i+1, total)
# 回溯
tmp.pop()
total -= candidates[i]
total = 0
helper(0, total)
return ans
class Solution(object):
def multiply(self, num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
num1 = int(num1)
num2 = int(num2)
return str(num1*num2)
problem solving ideas
For an array, sort it first, so that you can skip when there are the same numbers.
The idea of full arrangement is to choose a number in the current array as the first number, and the remaining numbers form a new array, and then Select a number in the array as the first number, and loop in turn. If
you encounter two or more identical numbers, skip them directly, otherwise there will be repetitions
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res = []
def dfs(nums, path):
if not nums:
res.append(path)
return
for i in range(len(nums)):
if i>0 and nums[i]==nums[i-1]:
continue
dfs(nums[:i]+nums[i+1:], path+[nums[i]])
dfs (nums, [])
return res
LeetCode-python 47. Full Arrangement II - Short Book
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res = []
def dfs(nums, path):
if not nums:
res.append(path)
return
for i in range(len(nums)):
if i>0 and nums[i]==nums[i-1]:
continue
dfs(nums[:i]+nums[i+1:], path+[nums[i]])
dfs (nums, [])
return res
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = nums[0]
for i in range(1, len(nums)):
nums[i] = nums[i] + max(0, nums[i-1])
return max(nums)
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
m, n = len(matrix), len(matrix[0])
# 顺时针方向(右下左上)
dm = [0, 1, 0, -1]
dn = [1, 0, -1, 0]
di = 0 # 方向指针
res = []
x = y = 0 # 位置
for _ in range(m*n): # 最多步长 m*n
res.append(matrix[x][y])
matrix[x][y] = 'v' # 访问过标记为 'v'(‘visited’)
# 下一步位置
x_temp = x + dm[di]
y_temp = y + dn[di]
# 判断下一步位置是否合理,若合理则更新位置,若不合理则改变方向并更新位置
if 0<=x_temp<m and 0<=y_temp<n and matrix[x_temp][y_temp]!='v':
x, y = x_temp, y_temp
else:
di = (di+1) % 4
x += dm[di]
y += dn[di]
return res
class Solution(object):
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
dp = [[1 for i in range(n)] for j in range(m)]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[-1][-1]
class Solution(object):
def uniquePathsWithObstacles(self, obstacleGrid):
"""
:type obstacleGrid: List[List[int]]
:rtype: int
"""
# 构造一个DP table
m = len(obstacleGrid)
n = len(obstacleGrid[0])
dp = [[0 for i in range(n)] for j in range(m)]
if obstacleGrid[0][0] == 1:
dp[0][0] = 0
else:
dp[0][0] = 1
for i in range(1, m):
if obstacleGrid[i][0] != 1:
dp[i][0] = dp[i-1][0]
for j in range(1, n):
if obstacleGrid[0][j] != 1:
dp[0][j] = dp[0][j-1]
for i in range(1, m):
for j in range(1, n):
if obstacleGrid[i][j] == 0:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[-1][-1]
class Solution(object):
def minPathSum(self, grid):
#此数组用于记忆化搜索
dp = [[0 for j in range(len(grid[0]))] for i in range(len(grid))]
for i in range(len(grid)):
for j in range(len(grid[0])):
#在起点的时候
if i == 0 and j == 0:
dp[i][j] = grid[0][0]
#在左边缘的时候
elif j == 0 and i != 0:
dp[i][j] = dp[i - 1][j] + grid[i][j]
#在上边缘的时候
elif i == 0 and j != 0:
dp[i][j] = dp[i][j-1] + grid[i][j]
# 普遍情况下
else:
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
return dp[len(grid)-1][len(grid[0])-1]
70. Climbing Stairs (Dynamic Programming)
class Solution(object):
def climbStairs(self, n):
"""
:type n: int
:rtype: int
"""
if n <= 1:
return n
# 初始化第一个和第二个阶梯
dp = [1, 2] + [0]*(n-2)
for i in range(2, n):
dp[i] = dp[i-1] + dp[i-2]
return dp[-1]
problem solving ideas
1. Divide the string by "/" and store
it in the array 2. Pop it out of the stack if it encounters "..."
3. Connect the remaining strings in the stack with '/' and return; if it is empty, return by default /
class Solution(object):
def simplifyPath(self, path):
"""
:type path: str
:rtype: str
"""
stack = []
path_array = path.split("/")
res_path = ""
for item in path_array:
if item not in ['', '.', '..']:
stack.append(item)
if item == '..':
if stack:
stack.pop(-1)
if [] == stack:
return '/'
for item in stack:
res_path += '/' + item + ''
return res_path
77. Combine (no)
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = [[]]
for i in range(len(nums)-1, -1, -1):
for subres in res[:]:
res.append(subres+[nums[i]])
return res
85. Largest rectangle (no) ※
LeetCode Hard 85 Maximum Rectangular Area Python_h-CSDN Blog_Maximum Rectangular Area Python
class Solution(object):
def maximalRectangle(self, matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
if matrix == [] or matrix[0] == []:
return 0
ans = 0
height = [0] * (len(matrix[0]) + 1)
for row in matrix:
for i in range(len(row)):
if row[i] == '1':
height[i] = height[i] + 1
else:
height[i] = 0
stack = [-1]
for i in range(len(height)):
while height[i] < height[stack[-1]]:
index = stack.pop()
h = height[index]
w = i - stack[-1] - 1
ans = max(ans, h * w)
stack.append(i)
return ans
class Solution(object):
def merge(self, nums1, m, nums2, n):
"""
:type nums1: List[int]
:type m: int
:type nums2: List[int]
:type n: int
:rtype: None Do not return anything, modify nums1 in-place instead.
"""
i = m-1
j = n-1
k = m+n-1
while i>=0 and j >=0:
if nums1[i] > nums2[j]:
nums1[k] = nums1[i]
i -= 1
k -=1
else:
nums1[k] = nums2[j]
j-=1
k-=1
while j >= 0:
nums1[k] = nums2[j]
k-=1
j-=1
return nums1
LeetCode 93. Recover IP Address | Python - Short Book
class Solution(object):
def restoreIpAddresses(self, s):
"""
:type s: str
:rtype: List[str]
"""
res = []
# 这里初始化长度为 4 的列表,分别存储对应 4 个片段
sub_res = [0] * 4
def dfs(seg_id, seg_first):
# 先看找到 4 个片段的情况
# 这里可能出现字符完全使用,以及未使用完全的情况
if seg_id == 4:
# 使用完全则添加到列表后返回
if seg_first == len(s):
res.append('.'.join(str(seg)for seg in sub_res))
# 未完全使用则直接返回
return
# 若未找到 4 个片段,则继续查找
# 这里要注意未找到 4 个片段却使用完字符的情况
if seg_first == len(s):
return
# 不能存在前导 0,如果有 0,那么当前片段只能为单独 0
if s[seg_first] == "0":
sub_res[seg_id] = 0
dfs(seg_id+1, seg_first+1)
addr = 0
# 每个片段选择的情况
for seg_last in range(seg_first, len(s)):
# 这里用整型来表示,后面再转换为字符串类型,避免过于频繁的切片
addr = addr * 10 + (ord(s[seg_last]) - ord('0'))
# 大于 0,但小于等于 255 的情况
if 0 < addr <= 255:
sub_res[seg_id] = addr
dfs(seg_id+1, seg_last+1)
# 其他情况直接跳出循环
else:
break
dfs(0, 0)
return res
[LeetCode] [Python] Verify binary search tree_dailu11's blog-CSDN blog
class Solution(object):
def validBST(self,root,small,large):
if root==None:
return True
if small>=root.val or large<=root.val:
return False
return self.validBST(root.left,small,root.val) and self.validBST(root.right,root.val,large)
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self.validBST(root,-2**32,2**32-1)
105. Construct Binary Tree from Preorder and Inorder Traversal Sequences
class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if inorder==[]:
return None
root = TreeNode(preorder[0])
#print(preorder,inorder)
x = inorder.index(root.val)#找到根在中序中的位置
root.left=self.buildTree(preorder[1:x+1],inorder[0:x])
root.right=self.buildTree(preorder[x+1:],inorder[x+1:])
return root