class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
self.res = []
trans = lambda path : ['.' * i + 'Q' + '.'*(len(path) - 1 - i) for i in path]
def recursion(n, path, pos):
if len(path) == n:
self.res.append(trans(path))
return
l, r, m = pos
l, r = [i-1 for i in l], [i + 1 for i in r]
total = l + r + m
for cand in range(n):
if cand in total:
continue
recursion(n, path + [cand], [l + [cand], r + [cand], m + [cand]])
recursion(n, [], [[], [], []])
return self.res
class Solution:
def totalNQueens(self, n: int) -> int:
self.res = []
trans = lambda path : ['.' * i + 'Q' + '.'*(len(path) - 1 - i) for i in path]
def recursion(n, path, pos):
if len(path) == n:
self.res.append(trans(path))
return
l, r, m = pos
l, r = [i-1 for i in l], [i + 1 for i in r]
total = l + r + m
for cand in range(n):
if cand in total:
continue
recursion(n, path + [cand], [l + [cand], r + [cand], m + [cand]])
recursion(n, [], [[], [], []])
return len(self.res)
或
class Solution:
def totalNQueens(self, n: int) -> int:
self.res = 0
def recursion(path, pos):
if len(path) == n:
self.res += 1
return
l, r = pos
l, r = [i-1 for i in l], [i + 1 for i in r]
total = l + r + path
for cand in range(n):
if cand in total:
continue
recursion(path + [cand], [l + [cand], r + [cand]])
for i in range(n // 2):
recursion([i], [[i], [i]])
self.res *= 2
if n % 2:
recursion([n // 2], [[n // 2], [n // 2]])
return self.res
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# 若list 中所有数均小于0
if max(nums) < 0:
return max(nums)
local_max, global_max = 0, 0
for num in nums:
local_max = max(0, local_max + num)
global_max = max(global_max, local_max)
return global_max
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
# matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
# 获取行数
row = len(matrix)
if row == 0 or len(matrix[0]) == 0:
return []
# 获取列数
col = len(matrix[0])
# 第一行为
res = matrix[0]
if row > 1:
# 获取最后一列 8, 12
for i in range(1, row):
res.append(matrix[i][col - 1])
# 获取最后一行 11, 10 ,9
for j in range(col - 2, -1, -1):
res.append(matrix[row -1][j])
if col > 1:
# 获取5
for i in range(row - 2, 0, -1):
res.append(matrix[i][0])
# 将剩下的 6, 7 作为新list 递归进spiralOrder
M = []
for k in range(1, row - 1):
t = matrix[k][1:-1]
M.append(t)
return res + self.spiralOrder(M)
class Solution:
def canJump(self, nums: List[int]) -> bool:
n = len(nums)
reach = 0
for i in range(n):
if reach >= n - 1 or reach < i:
break
reach = max(reach, nums[i] + i)
return reach >= n - 1
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
result = []
intervals.sort(key = lambda x : x[0])
i = 0
while i < len(intervals):
cur_start = intervals[i][0]
cur_end = intervals[i][1]
if result:
prev_start, prev_end = result[-1]
hi = min(prev_end, cur_end)
lo = max(prev_start, cur_start)
if lo <= hi:
if cur_end > prev_end:
result[-1][1] = cur_end
else:
result.append(intervals[i])
else:
intervals.append(intervals[i])
i += 1
return result
或
class Solution:
def merge(self, intervals):
"""
:type intervals: List[Interval]
:rtype: List[Interval]
"""
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
pre, cur, n = 0, 1, len(intervals)
while cur < n:
if intervals[pre][1] < intervals[cur][0]:
pre += 1
intervals[pre] = intervals[cur]
else:
intervals[pre][1] = max(intervals[pre][1], intervals[cur][1])
cur += 1
return intervals[:pre+1]
class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
index = 0
while(index < len(intervals) and newInterval[0] > intervals[index][0]):
index += 1
intervals.insert(index, newInterval)
res = []
last = None
for interval in intervals:
if not last or last[1] < interval[0]:
res.append(interval)
last = interval
else:
last[1] = max(last[1], interval[1])
return res
class Solution:
def lengthOfLastWord(self, s: str) -> int:
count = 0
local_count = 0
for i in range(len(s)):
if s[i] == ' ':
local_count = 0
else:
local_count += 1
count = local_count
return count
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
# 初始化结果矩阵
matrix = []
for i in range(n):
matrix.append([0 for j in range(n)])
# 初始化行,列索引和值
rowBegin = 0
rowEnd = n - 1
colBegin = 0
colEnd = n - 1
number = 1
while colBegin <= colEnd and rowBegin <= rowEnd:
# 对第一行赋值
for i in range(colBegin, colEnd + 1):
matrix[rowBegin][i] = number
number += 1
rowBegin += 1
# 对最后一列赋值
for i in range(rowBegin, rowEnd + 1):
matrix[i][colEnd] = number
number += 1
colEnd -= 1
# 最后一行
if rowBegin <= rowEnd:
for i in range(colEnd, colBegin - 1, -1):
matrix[rowEnd][i] = number
number += 1
rowEnd -= 1
# 最后的行
if colBegin <= colEnd:
for i in range(rowEnd, rowBegin - 1, -1):
matrix[i][colBegin] = number
number += 1
colBegin += 1
return matrix
class Solution:
def getPermutation(self, n: int, k: int) -> str:
ans = ''
digits = [i for i in range(1, n + 1)]
for i in range(n -1 , -1, -1):
curbase = math.factorial(i)
curindex = (k - 1) // curbase
ans += str(digits[curindex])
digits.remove(digits[curindex])
k = k - curindex * curbase
return ans
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
# 链表长度大于2才可以旋转
if head is None or head.next is None:
return head
# 计算链表长度
n = 0
p = head
while p:
n += 1
p = p.next
# 用k对n进行取余,判断实际需要移动几次(每n次和原链表形状一致)
k = k % n
if k == 0:
return head
# 计算要移动的位置
p1, p2 = head, head
for i in range(k):
p2 = p2.next
while p2 and p2.next:
p1 = p1.next
p2 = p2.next
# 旋转链表
output = p1.next
p1.next = None
p2.next = head
return output
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 初始化第一行及第一列全为1
# 剩余格子值为该格子相邻左边、上边格子的和
# 依次更新第二行,第三行
if m == 0 or n == 0:
return 1
# 初始化时候可以将list全部初始化为1,再计算除了第一行第一列的值
cache = [[1] * n for _ in range(m)]
# print(cache)
# [[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]]
for i in range(1, m):
for j in range(1, n):
cache[i][j] = cache[i - 1][j] + cache[i][j - 1]
return cache[-1][-1]
或
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 或者采用排列组合,先计算到达目的地需要多少次右边n和多少次向下m移动
# 如题目中,需要进行6次右,2次下
# C(2, 8) / C(6, 8)
res = 1
div = 1
for i in range(m, m+n-1):
res *= i
div *= (i - m + 1)
return res // div
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
# 初始化第一行全为1, 遇到障碍物,障碍物及右边的所有格子为0
# 再更新第二行第一列为1
# 第二行剩余格子值为该格子相邻左边、上边格子的和
# 依次更新第三行
if not obstacleGrid:
return 0
m, n = len(obstacleGrid), len(obstacleGrid[0])
cache = [[0] * n for _ in range(m)]
cache[0][0] = 1
for i in range(m):
for j in range(n):
# 遇到障碍物
if obstacleGrid[i][j] == 1:
cache[i][j] = 0
else:
if i > 0:
cache[i][j] += cache[i - 1][j]
if j > 0:
cache[i][j] += cache[i][j - 1]
return cache[-1][-1]
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
if not grid:
return 0
# 采用动态规划思想
# 初始化动态规划list, 外加一层padding
dp = [[2**31-1 for _ in range(len(grid[0]) + 1)] for _ in range(len(grid) + 1)]
for i in range(1, len(grid) + 1):
for j in range(1, len(grid[0]) + 1):
if i == 1 and j == 1:
dp[i][j] = grid[i - 1][j - 1]
continue
# 动态规划方程
dp[i][j] = grid[i - 1][j - 1] + min(dp[i - 1][j], dp[i][j - 1])
return dp[-1][-1]
这道题应该难在考虑各种情况。所有的字符可以分为六大类,空格,符号,数字,小数点,自然底数和其他字符,我们需要五个标志变量,num, dot, exp, sign分别表示数字,小数点,自然底数和符号是否出现,numAfterE表示自然底数后面是否有数字,那么我们分别来看各种情况:
- 空格: 我们需要排除的情况是,当前位置是空格而后面一位不为空格,但是之前有数字,小数点,自然底数或者符号出现时返回false。
- 符号:符号前面如果有字符的话必须是空格或者是自然底数,标记sign为true。
- 数字:标记num和numAfterE为true。
- 小数点:如果之前出现过小数点或者自然底数,返回false,否则标记dot为true。
- 自然底数:如果之前出现过自然底数或者之前从未出现过数字,返回false,否则标记exp为true,numAfterE为false。
- 其他字符:返回false。
最后返回num && numAfterE即可。
class Solution:
def isNumber(self, s: str) -> bool:
try:
float(s)
return True
except:
return False
或
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
if not s:
return False
INVALID = 0
SPACE = 1
SIGN = 2
DIGIT = 3
DOT = 4
E = 5
transition = [
[-1,0,3,1,2,-1],
[-1,8,-1,1,4,5],
[-1,-1,-1,4,-1,-1],
[-1,-1,-1,1,2,-1],
[-1,8,-1,4,-1,5],
[-1,-1,6,7,-1,-1],
[-1,-1,-1,7,-1,-1],
[-1,8,-1,7,-1,-1],
[-1,8,-1,-1,-1,-1]
]
state = 0
for i in s:
if i == ' ':
idx = SPACE
elif i == '-' or i == '+':
idx = SIGN
elif i >= '0' and i <= '9':
idx = DIGIT
elif i == '.':
idx = DOT
elif i == 'E' or i == 'e':
idx = E
else:
idx = INVALID
state = transition[state][idx]
if state == -1:
return False
return state == 1 or state == 4 or state == 7 or state == 8
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
if digits[-1] == 9:
flag = 1
else:
flag = 0
for i in range(len(digits)-1, -1, -1):
if i == len(digits)-1:
flag = 1
if digits[i] + flag > 9:
digits[i] = 0
flag = 1
else:
digits[i] = digits[i]+flag
flag = 0
if flag:
digits.insert(0,1)
return digits
或
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
for i in reversed(range(len(digits))):
if digits[i] == 9:
digits = 0
else:
digits[i] += 1
return digits
# input : 9 -> output : 10
digits[0] = 1
digits.append(0)
return digits
class Solution:
def addBinary(self, a: str, b: str) -> str:
result, carry, val = '', 0, 0
for i in range(max(len(a), len(b))):
val = carry
if i < len(a):
val += int(a[-(i + 1)])
if i < len(b):
val += int(b[-(i + 1)])
carry, val = val // 2, val % 2
result += str(val)
if carry:
result += str(1)
return result[::-1]
class Solution:
def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
# res: 返回结果
# line: 缓存每一行单词
# counter: 统计当前进入line的单词总长度
res, line, counter = [], [], 0
for word in words:
# 采用贪心策略,每一行尽可能多放
if counter + len(word) + len(line) > maxWidth:
# 一行放不下时候,另起一行
for i in range(maxWidth - counter):
line[i % max(len(line) - 1, 1)] += ' '
res.append(''.join(line))
line, counter = [], 0
line += [word]
counter += len(word)
# ljust()左对齐
return res + [' '.join(line).ljust(maxWidth)]
class Solution:
def mySqrt(self, x: int) -> int:
if x < 2:
return x
left, right = 1, x // 2
while left <= right:
mid = left + (right - left) // 2
if mid > x / mid:
right = mid - 1
else:
left = mid + 1
return left - 1
class Solution:
def climbStairs(self, n: int) -> int:
# n = 1, 1种
# n = 2, 2种
# n = 3, 3种
# ....
# n = n , n + n - 1种
# 斐波那契数列(结果 = 前两个结果之和)
prev, current = 0, 1
for i in range(n):
prev, current = current, prev + current
return current
class Solution:
def simplifyPath(self, path: str) -> str:
result = []
path_list = path.split('/')
for p in path_list:
if p:
if p == '..':
if result:
result.pop()
elif p == '.':
continue
else:
result.append(p)
res = '/' + '/'.join(result)
return res
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
# topens 用于堆放(word1*, word2*..)
# visited 用于存放已见过的(word1*, word2*..)词语对
# 用删除的方式,把已经匹配好的word1*, word2*字母删去,
# 三种基本操作
# word1*删去头字母
# word2*删去头字母
# 两词同时删去头字母
w1, w2, opened = word1, word2, set()
topens = [(w1, w2, 0)]
while True:
(w1, w2, value) = topens.pop(0)
if (w1, w2) in opened:
continue
if w1 == w2:
return value
opened.add((w1, w2))
while w1 and w2 and w1[0] == w2[0]:
w1, w2 = w1[1:], w2[1:]
value += 1
topens += [(w1[1:], w2, value),
(w1, w2[1:], value),
(w1[1:], w2[1:], value)
]
return -1
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
m, n = len(matrix), len(matrix[0])
zero_row, zero_col = False, False
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
matrix[i][0] = matrix[0][j] = 0
zero_row = True if i == 0 else zero_row
zero_col = True if j == 0 else zero_col
for j in range(1, n):
if matrix[0][j] == 0:
for i in range(1, m):
matrix[i][j] = 0
for i in range(1, m):
if matrix[i][0] == 0:
for j in range(1, n):
matrix[i][j] = 0
if zero_row:
for j in range(n):
matrix[0][j] = 0
if zero_col:
for i in range(m):
matrix[i][0] = 0
return
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
# 升序矩阵,采用二分法
m, n = len(matrix), len(matrix[0])
if m == 0:
return False
left = 0
right = m * n
while left < right:
mid = (left + right) // 2
i = mid // n
j = mid % n
if matrix[i][j] < target:
left = mid + 1
elif matrix[i][j] > target:
right = mid
else:
return True
return False
class Solution:
def sortColors(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
p, q = 0, 0
k = len(nums) - 1
while q <= k:
if p < q and nums[q] == 0:
nums[p], nums[q] = nums[q], nums[p]
p += 1
elif nums[q] == 2:
nums[q], nums[k] = nums[k], nums[q]
k -= 1
else:
q += 1
class Solution:
def minWindow(self, s: str, t: str) -> str:
# 创建一个键值对,统计每个字符出现次数
d = dict(collections.Counter(t)) # {'A':0, 'B':1...}
# 用于描述ABC中多少字符满足要求
formed = 0
# 左指针
slow = 0
# 记录最短长度及substring
min_str = None
min_length = sys.maxsize - 1
for fast in range(len(s)):
ch = s[fast]
fast += 1
if ch not in d:
continue
# 更新词频
d[ch] -= 1
if d[ch] == 0:
formed += 1
while formed == len(d) and slow <= fast:
curr_length = fast - slow
if curr_length < min_length:
min_length = curr_length
min_str = s[slow:fast]
# 更新左边界
ch = s[slow]
slow += 1
if ch not in d:
continue
d[ch] += 1
if d[ch] == 1:
formed -= 1
return min_str if min_str is not None else ''
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
import itertools
return list(itertools.combinations(range(1, n + 1), k))
或
class Solution:
def combine(self, n, k):
ans = []
nums = [i + i for i in range(n)]
def dfs(last, now):
if len(now) == k:
ans.append(now)
for i in range(len(last)):
dfs(last[i + 1:], now + [last[i]])
dfs(nums, [])
return ans
#方法1:递归方法,[1,2,3] --> ([1] + [2,3]子集)+[2,3]子集
class Solution:
def subsets(self, nums) :
res = []
if not nums:
return [[]]
else:
sub = self.subsets(nums[1:])
res = res + sub
for s in sub:
res.append(nums[:1]+s)
return res
或
#方法2 位运算方法:对每一位为1的表示这一位的数字存在,例如对于输入[1,2,3] 编码i=001,表示只含有3,编码i=101.表示含有1,3
class Solution:
def subsets(self, nums):
t=len(nums)
res=[]
for i in range(2**t):
tmp=[]
for j in range(t):
if i&(1<<j):
tmp.append(nums[t-1-j])
res.append(tmp)
return res
#方法三 排列组合
class Solution:
def subsets(self, nums):
from itertools import combinations
print([list(s) for s in list(combinations(nums, 2))])
return sum([list(combinations(nums, i)) for i in range(len(nums) + 1)], [])
#方法四:遇到一个数添加一下
class Solution:
def subsets(self, nums):
res = []
res.append([])
for x in nums:
new = [s+ [x] for s in res]
res = res + new
return res
#方法五:回溯方法 https://leetcode-cn.com/problems/subsets/solution/hui-su-jie-fa-by-jawhiow/
class Solution(object):
def __init__(self):
self.result_all = None
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
self.result_all = []
self.dfs(nums, 0, 0, [])
return self.result_all
def dfs(self, nums, n, start, result):
self.result_all.append(result[:])
if len(nums) == n:
return
for i in range(start, len(nums)):
result.append(nums[i])
self.dfs(nums, n + 1, i + 1, result)
result.pop()
return
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
for i in range(len(board)):
for j in range(len(board[0])):
# helper(board, i, j, word本身, word索引)
if self.helper(board, i, j, word, 0):
return True
return False
def helper(self, board, i, j, word, wordIndex):
# 说明已经找到了答案
if wordIndex == len(word):
return True
# board[0, x] 或者 board[x, len(board)]等边界情况及查找结果不匹配
if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[wordIndex] != board[i][j]:
return False
# 避免每个字母使用多次,用特殊字母标记
board[i][j] = '#'
# 开始上下左右查找
found = self.helper(board, i + 1, j, word, wordIndex + 1)\
or self.helper(board, i, j + 1, word, wordIndex + 1)\
or self.helper(board, i - 1, j, word, wordIndex + 1)\
or self.helper(board, i, j - 1, word, wordIndex + 1)
# 查找完后,复原标记
board[i][j] = word[wordIndex]
return found
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# 满足新要求的数组索引
j = 0
# 用于遍历索引
i = 0
count = 1
while i < len(nums):
if i < len(nums) - 1 and nums[i] == nums[i + 1]:
count += 1
else:
# 插入j为末尾的新标记数组
d = min(count, 2)
for k in range(d):
nums[j] = nums[i]
j += 1
# 新的起点
count = 1
# 下一个判断索引
i += 1
return len(nums[:j])
class Solution:
def search(self, nums: List[int], target: int) -> bool:
# num_len = len(nums)
# if num_len == 0:
# return False
# mid = num_len // 2
# result = False
# if nums[mid] == target:
# return True
# elif num_len == 1:
# return target == nums[0]
# elif target > nums[mid]:
# if mid > 0 and (nums[mid - 1] > nums[mid] or nums[0] > nums[mid]):
# result = self.search(nums[:mid], target)
# return result if result is True else self.search(nums[mid+1:], target)
# else:
# if mid < num_len - 1 and (nums[mid] > nums[mid + 1] or nums[mid+1] > nums[-1]):
# result = self.search(nums[mid+1:], target)
# return result if result is True else self.search(nums[:mid], target)
left = 0
right = len(nums)-1
while left <= right:
mid = (left+right)//2
if nums[mid]==target:
return True
if nums[mid] == nums[left] == nums[right]:
left += 1
right -= 1
elif nums[mid]>=nums[left]:
if nums[left]<=target<=nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid]<=target<=nums[right]:
left = mid + 1
else:
right = mid - 1
return False
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
if head == None or head.next == None:
return head
tmp = ListNode(-1)
slow = tmp
fast = head
while fast:
if fast.next and fast.val == fast.next.val:
ee = fast.val
while fast and ee == fast.val:
fast = fast.next
else:
slow.next = ListNode(fast.val)
slow = slow.next
fast = fast.next
return tmp.next
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
current = head
while current:
runner = current.next
while runner and runner.val == current.val:
runner = runner.next
current.next = runner
current = runner
return head
class Solution:
def largestRectangleArea(self, heights: List[int]) -> int:
# 定义栈
stack = []
# 加上首尾标记处理特殊情况
heights = [0] + heights + [0]
res = 0
for i in range(len(heights)):
while stack and heights[i] < heights[stack[-1]]:
# 找到最大栈顶元素
top = stack.pop()
# 该元素右侧
r = i - 1
# 该元素左侧
l = stack[-1] + 1
# 计算面积
area = (r - l + 1) * heights[top]
res = max(area, res)
stack.append(i)
return res
class Solution:
def maximalRectangle(self, matrix: List[List[str]]) -> int:
res = 0
for i, row in enumerate(matrix):
if i == 0:
_heights = [int(ch == '1') for ch in row]
else:
for j in range(len(row)):
if row[j] == '0':
_heights[j] = 0
else:
_heights[j] += 1
stack = []
height = [0] + _heights + [0]
for j in range(len(height)):
while stack and height[j] < height[stack[-1]]:
top = stack.pop()
l = stack[-1] + 1
r = j - 1
area = (r - l + 1) * height[top]
res = max(area, res)
stack.append(j)
return res
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def partition(self, head: ListNode, x: int) -> ListNode:
dummySmaller, dummyGreater = ListNode(-1), ListNode(-1)
smaller, greater = dummySmaller, dummyGreater
while head:
if head.val < x:
smaller.next = head
smaller = smaller.next
else:
greater.next = head
greater = greater.next
head = head.next
smaller.next = dummyGreater.next
greater.next = None
return dummySmaller.next
class Solution:
def isScramble(self, s1: str, s2: str) -> bool:
if len(s1) != len(s2):
return False
if s1 == s2:
return True
if sorted(s1) != sorted(s2):
return False
for i in range(1, len(s1)):
if self.isScramble(s1[:i], s2[:i]) and self.isScramble(s1[i:], s2[i:]) or \
(self.isScramble(s1[:i], s2[-i:]) and self.isScramble(s1[i:], s2[:-i])):
return True
return False
或
class Solution:
def isScramble(self, s1: str, s2: str) -> bool:
n = len(s1)
dp = [[[False]*(n+1) for _ in range(n)] for _ in range(n)]
for i in range(n):
for j in range(n):
dp[i][j][1] = s1[i]==s2[j]
for l in range(2, n+1):
for i in range(n-l+1):
for j in range(n-l+1):
for k in range(1, l):
if dp[i][j][k] and dp[i+k][j+k][l-k] or \
dp[i][j+l-k][k] and dp[i+k][j][l-k]:
dp[i][j][l] = True
break
return dp[0][0][n]
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
while m > 0 and n > 0:
# 从后往前判断,找到nums1和nums2中最大的数放在末尾
if nums1[m-1] < nums2[n-1]:
nums1[m-1+n] = nums2[n-1]
# 已经放入一个数字,因此减少一位
n = n -1
else:
# 如果最大数在nums1中已经排好序,与最后一个位置元素交换
nums1[m-1+n], nums1[m-1] = nums1[m-1], nums1[m-n+1]
m = m - 1
# 插入后,将nums1中的0使用nums2剩下的元素替换
if m == 0 and n > 0:
nums1[:n] = nums2[:n]
return nums1
class Solution:
def grayCode(self, n: int) -> List[int]:
if(n==0):return [0]
l=[0,1]
t=2
h=1
while(h<n):
e=l[::-1]
for i in e:
l.append(i+t)
t=t*2
h=h+1
return l
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res = [[]]
for i in nums:
cr = []
for j in res:
if j + [i] not in res:
cr += [j + [i]]
res += cr
return res
或
class Solution:
def subsetsWithDup(self, nums: 'List[int]') -> 'List[List[int]]':
nums.sort()
res = []
self.dfs(nums,0,[],res)
return res
def dfs(self,nums,k,path,res):
res.append(path)
for i in range(k,len(nums)):
if i > k and nums[i] == nums[i-1]:continue
self.dfs(nums,i+1,path+[nums[i]],res)
class Solution:
def numDecodings(self, s: str) -> int:
from functools import lru_cache
# 存储之前找到的结果到内存中,减少计算
@lru_cache(None)
def helper(n):
if n == 0:
return 1
ans = 0
if n >= 1 and s[n-1] != '0':
ans += helper(n-1)
if n >= 2 and 10 <= int(s[n-2:n]) <= 26:
ans += helper(n-2)
return ans
return helper(len(s))
或
def numDecodings(self, s):
dp = [-1 for i in range(len(s)+1)]
dp[0] = 1
def helper(n):
if dp[n] != -1:
return dp[n]
ans = 0
if n >= 1 and s[n-1] != '0':
ans += helper(n-1)
if n >= 2 and 10 <= int(s[n-2:n]) <= 26:
ans += helper(n-2)
dp[n] = ans
return ans
return helper(len(s))
或
def numDecodings(self, s):
n = len(s)
if n == 1:
return 1 if s[0] != '0' else 0
prev2 = 1
prev1 = 1 if s[0] != '0' else 0
for i in range(2, len(s) + 1):
cur = 0
if s[i-1] != '0':
cur += prev1
if 10 <= int(s[i-2:i]) <= 26:
cur += prev2
prev2 = prev1
prev1 = cur
return prev1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
before = dummy
m = left
n = right
for i in range(0, m - 1):
before = before.next
start = before.next
then = start.next
for i in range(0, n - m):
start.next = then.next
then.next = before.next
before.next = then
then = start.next
return dummy.next
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
res = []
def backtrace(cnt = 0, ip = '', s = ''):
if cnt == 4:
if s == '':
res.append(ip[:-1])
return
if len(s) > 0:
backtrace(cnt + 1, ip + s[0] + '.', s[1:])
if len(s) > 1 and s[0] != '0':
backtrace(cnt + 1, ip + s[:2] + '.', s[2:])
if len(s) > 2 and s[0] != '0' and int(s[0:3]) < 256:
backtrace(cnt + 1, ip + s[:3] + '.', s[3:])
backtrace(0, '', s)
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def helper(root):
if not root:
return
helper(root.left)
res.append(root.val)
helper(root.right)
helper(root)
return res
或
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res = []
stack = []
cur = root
while cur or stack:
while cur:
stack.append(cur)
cur = cur.left
cur = stack.pop()
res.append(cur.val)
cur = cur.right
return res
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def generateTrees(self, n: int) -> List[TreeNode]:
if n == 0:
return []
return self.helper(1, n)
def helper(self, start, end):
if start > end:
return [None]
res = []
# 任取一个root作为该树的root
for cur_root in range(start, end + 1):
# 获取左右树的结构
left = self.helper(start, cur_root - 1)
right = self.helper(cur_root + 1, end)
# 对所有可能的树进行组合
for l in left:
for r in right:
root = TreeNode(cur_root)
root.left = l
root.right = r
res.append(root)
return res
class Solution:
def numTrees(self, n: int) -> int:
# numTrees[4] = numTrees[0] * numTrees[3]+
# numTrees[3] * numTrees[0]+
# numTrees[1] * numTrees[2]+
# numTrees[2] * numTrees[1]
numTree = [1] * (n + 1)
for nodes in range(2, n + 1):
total = 0
for root in range(1, nodes + 1):
left = root - 1
right = nodes - root
total += numTree[left] * numTree[right]
numTree[nodes] = total
return numTree[n]
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
n1 = len(s1)
n2 = len(s2)
n = len(s3)
if n1+n2 != n:
return False
# dp(i,j)表示是s1的前i个字符和s2的前j个字符能否交错成s3的前i+j个字符
# 因此答案为dp(n1,n2)
dp = [[False for _ in range(n2+1)] for _ in range(n1+1)]
dp[0][0] = True
# 初始化dp[0][i]和dp[i][0]
for i in range(1,n1+1):
dp[i][0] = dp[i-1][0] and (s1[i-1] == s3[i-1])
for i in range(1,n2+1):
dp[0][i] = dp[0][i-1] and (s2[i-1] == s3[i-1])
# 填写dp
for i in range(1,n1+1):
for j in range(1,n2+1):
dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i+j-1]) or (dp[i][j-1] and
s2[j-1] == s3[i+j-1])
return dp[n1][n2]
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
return self.valid(root, float('-inf'), float('inf'))
def valid(self, root, min, max):
if not root:
return True
if root.val >= max or root.val <= min: return False
return self.valid(root.left, min, root.val) and self.valid(root.right, root.val, max)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.fnode = None
self.snode = None
self.preNode = TreeNode(float("-inf"))
def order(root):
if not root:
return
order(root.left)
if self.snode == None and self.preNode.val >= root.val:
self.fnode = self.preNode
if self.fnode and self.preNode.val >= root.val:
self.snode = root
self.preNode = root
order(root.right)
order(root)
self.fnode.val , self.snode.val = self.snode.val , self.fnode.val
或
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
fnode = None
snode = None
pre = TreeNode(float("-inf"))
stack = []
p = root
while p or stack:
while p:
stack.append(p)
p = p.left
p = stack.pop()
if not fnode and pre.val > p.val: #这是存在异常的情况
fnode = pre #找到第一个位置的异常点
if fnode and pre.val > p.val:
snode = p #找到第二个位置的异常点,因为题意说了,只有两个异常,所以无论两者是否挨在一起,只要交换过来值,就一定是对的,此代码不具有泛化性
pre = p
p = p.right
fnode.val,snode.val = snode.val,fnode.val
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if p is None and q is None:
return True
if p is not None and q is not None:
return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
return False