一天一道LeetCode(61-90)
一天一道LeetCode(61-90)
文章目录
- 一天一道LeetCode(61-90)
- 61.旋转链表
- 62.不同路径
- 63.不同路径 II
- 64.最小路径和
- 65.有效数字(未解决)
- 66.加一
- 67.二进制求和
- 68.文本左右对齐
- 69.x 的平方根
- 70.爬楼梯
- 71.简化路径
- 72.编辑距离
- 73.矩阵置零
- 74.搜索二维矩阵
- 75.颜色分类
- 76.最小覆盖子串
- 77.组合
- 78.子集
- 79.单词搜索
- 80.删除排序数组中的重复项 II
- 81.搜索旋转排序数组 II
- 82.删除排序链表中的重复元素 II
- 83.删除排序链表中的重复元素
- 84.柱状图中最大的矩形
- 85.最大矩形
- 86.分隔链表
- 87.扰乱字符串
- 88.合并两个有序数组
- 89.格雷编码(未解决)
- 90.子集 II
61.旋转链表
题目:
给定一个链表,旋转链表,将链表每个节点向右移动k个位置,其中k是非负数
实例:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
class ListNode:def __init__(self, x):self.val = xself.next = None
class Solution:def rotateRight(self, head, k):if not head:return None# 获取链表长度p = headlength = 0while p :length += 1p = p.next# 让k对length取余,避免重复循环导致超时k = k % lengthif k == 0:return headpre, post = head, head# 让一个指针先走k步for i in range(k):post = post.next# 两个指针一起走while post.next:pre = pre.nextpost = post.nexttmp = pre.nextpre.next = Nonepost.next = headreturn tmp
62.不同路径
题目:
一个机器人位于一个m x n 网格的左上角(起始点在下图中标记为"start"),机器人每次只能向下或者向右移动一步,机器人试图到达网格的右下角(图中标记为"finish"),总共有多少条不同的路径?
实例:
输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
输入: m = 7, n = 3
输出: 28
思路:
动态规划
机器人智能向下或者向右移动一步,对于任意的i, j
,机器人只能从左侧或者上方移动过来,特别的对于上边界或左边界,机器人只有一种移动方式,就有如下公式:
d p [ i ] [ j ] = { 1 (i = 0, j = 0) d p [ i ] [ j − 1 ] (i = 0, j ≠ 0) d p [ i − 1 ] [ j ] (i ≠ 0, j = 0) d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] (i ≠ 0, j ≠ 0 ) dp[i][j] = \begin{cases}1& \text{(i = 0, j = 0)}\\dp[i][j - 1]& \text{(i = 0, j $\neq$ 0)}\\dp[i - 1][j]& \text{(i $\neq$ 0, j = 0)}\\dp[i - 1][j] + dp[i][j - 1]& \text{(i $\neq$ 0, j $\neq 0 $)}\end{cases} dp[i][j]=⎩⎪⎪⎪⎨⎪⎪⎪⎧1dp[i][j−1]dp[i−1][j]dp[i−1][j]+dp[i][j−1](i = 0, j = 0)(i = 0, j = 0)(i = 0, j = 0)(i = 0, j =0)
在该题中还可以简化为:
d p [ i ] [ j ] = { 1 (i = 0 or j = 0) d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] (i ≠ 0 , j ≠ 0 ) dp[i][j] = \begin{cases}1& \text{(i = 0 or j = 0)}\\dp[i - 1][j] + dp[i][j - 1]& \text{(i $\not= 0 $, j $\not= 0$)}\end{cases} dp[i][j]={1dp[i−1][j]+dp[i][j−1](i = 0 or j = 0)(i =0, j =0)
class Solution:def uniquePaths(self, m, n):dp[[1]*n for _ in range(m)]for i in range(1, m):for j in range(1, n):dp[i][j] = dp[i][j - 1] + dp[i - 1][j]return dp[-1][-1]
63.不同路径 II
题目:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用1和0来表示
实例:
输入:
[[0,0,0],[0,1,0],[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
class Solution:def uniquePathsWithObstacles(self, obstacleGrid):m, n = len(obstacleGrid[0]), len(obstacleGrid)dp = [1] + [0]*mfor i in range(0, n):for j in range(0, m):dp[j] = 0 if obstacleGrid[i][j] else dp[j]+dp[j-1]return dp[-2]
64.最小路径和
题目:
给定一个包含非负整数的m x n网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和最小(每次只能向下或者向右移动一步)
实例:
输入:
[[1,3,1],[1,5,1],[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小
思路:
动态规划
状态定义:设dp为大小m x n矩阵,其中dp[i][j]的值代表走到(i, j)的最小路径和
转移方程:根据题目,只能向右或者向下走,也就是说,当前单元格(i, j)只能从左方单元格(i - 1, j)或上方单元格(i, j - 1)走到,因此只需要考虑矩阵的左边界和上边界
走到当前单元格(i, j)的最小路径和 = “从左方单元格(i - 1, j)与从上方单元格(i, j - 1)走来的两个最小路径和中较小的 + 当前单元格值grid[i][j],具体分为以下4中情况:
- 1.当左边和上边都不是矩阵边界时:即当 i ≠ 0 , j ≠ 0 i \not= 0, j \not= 0 i=0,j=0时,dp[i][j] = min(dp[i - 1][j], dp[i][j - 1] + grid[i][j])
- 2.当只有左边是矩阵边界时:只能从上面来,即当 i = 0 , j ≠ 0 i = 0, j \not= 0 i=0,j=0时,dp[i][j] = dp[i][j - 1] + grid[i][j]
- 3.当只有上边是矩阵边界时:只能从左边来,即当 i ≠ 0 , j = 0 i \neq 0, j = 0 i=0,j=0 时,dp[i][j] = dp[i - 1][j] + grid[i][j]
- 4.当左边和上边都是矩阵边界时:即当 i = 0 , j = 0 i = 0, j = 0 i=0,j=0时,其实就是起点,dp[i][j] = grid[i][i]
初始状态:dp初始化即可,不需要修改初始0值
class Solution:def minPathSum(self, grid):for i in range(len(grid)):for j in range(len(grid[0])):if i == j == 0:continueelif i == 0:grid[i][j] = grid[i][j - 1] + grid[i][j]elif j == 0:grid[i][j] = grid[i - 1][j] + grid[i][j]else:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j]return grid[-1][-1]
65.有效数字(未解决)
题目:
验证给定的字符串是否可以解释为十进制数字
实例:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
说明:
可能存在于有效十进制数字中的字符表:
- 数字 0-9
- 指数 - “e”
- 正/负号 - “+”/"-"
- 小数点 - “.”
66.加一
题目:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一
最高位数字存放在数组的首位,数组中每个元素只存储单个数字
可以假设除了整数0之外,这个整数不会以0开头
实例:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321
# 投机解法
class Solution:def plusOne(self, digits):cur = ''for ele in digits:cur += str(ele)cur = int(cur) + 1res = [int(i) for i in str(cur)]return res
# 正常解法
class Solution:def plusOne(self, digits):carry = 1for i in range(len(digits)-1, -1, -1):if digits[i] == 9:if carry == 1:digits[i] = 0carry = 1else:digits[i] += carrycarry = 0if carry == 1:digits = [1] + digitsreturn digits
67.二进制求和
题目:
给你一个二进制字符串,返回他们的和(用二进制表示)
输入为非空字符串且只包含数字1和0
实例:
输入: a = "11", b = "1"
输出: "100"
输入: a = "1010", b = "1011"
输出: "10101"
提示:
- 每个字符串仅由字符
'0'
或'1'
组成。 1 <= a.length, b.length <= 10^4
- 字符串如果不是
"0"
,就都不含前导零。
class Solution:def addBinary(self, a, b):if len(a) < len(b):a, b = b, an = len(a)# 补齐b不足的位为0b = '0' * (n - len(b)) + bresult = ''summ = 0 # 进位值for i in range(n):a_1 = int(a[-i-1])b_1 = int(b[-i-1])# 当前数位相加余2,连接更小位数的值result = str((a_1 + b_1 + summ) % 2) + result# 当前位数之和整除2,得到下一位运算的进位值summ = (a_1 + b_1 + summ) // 2# 判断最高位是否需要进位if summ == 1:result = '1' + resultreturn result
# 内置方法
class Solution:def addBinary(self, a, b):return bin(int(a, 2) + int(b, 2))[2:]
68.文本左右对齐
题目:
给定一个单词数组和一个长度maxWidth,重新排版单词,使其成为每行恰好有maxWidth个字符,且左右两段对齐的文本
应该使用“贪心算法”来放置给定的单词,也就是说,尽可能多的往每行中放置单词,必要时可以使用空格填充,使得每行恰好有maxWidth个字符
要求尽可能均匀分配单词间的空格数量,如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数
文本的最后一行应为左对齐,且单词之间不插入额外的空格
说明:
- 单词是指由非空格字符组成的字符序列。
- 每个单词的长度大于 0,小于等于 maxWidth。
- 输入单词数组
words
至少包含一个单词。
实例:
输入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
输出:
["This is an","example of text","justification. "
]
输入:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
输出:
["What must be","acknowledgment ","shall be "
]
解释: 注意最后一行的格式应为 "shall be " 而不是 "shall be",因为最后一行应为左对齐,而不是左右两端对齐。 第二行同样为左对齐,这是因为这行只包含一个单词
输入:
words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
输出:
["Science is what we","understand well","enough to explain to","a computer. Art is","everything else we","do "
]
思路:
设定一下几个变量:
ans 最后答案 / cur_c 当前行的字母数 / cur_w 当前行的单词数 / wl 当前行的单词列表
然后一个单词一个单词的过,判断加上这个单词是否会超过最大长度,一行的最低长度是:
cur_c + cur_w - 1
如果大于maxWidth,就把这一行加入ans中,所有单词过完了再把余下的词放入最后一行
如何安排每一行的单词:
1.如果这一行只有一个单词,单词左对齐,后面补满空格
2.一行多个单词
空格正好可以平均分配,求出平均每个间隔几个空格,直接调用python的join方法
有多余的空格,题目要求左边空格多于右边,先算平均每个间隔几个空格,然后余下几个,如果平均b个,余下x个,则前x个间隔空b + 1个,后面的都空b个
class Solution:def fullJustify(self, words, maxWidth):ans = [] # 最后的答案cur_c = 0 # 当前行的字母数cur_w = 0 # 当前行的单词数wl = [] # 当前行的单词列表for i, wd in enumerate(words):l = len(wd)if cur_c + l + cur_w > maxWidth: # 加上这个单词是否会超过最大长度if cur_w == 1: # 当前行仅有一个超长的单词,后面全部补空格ans.append(wl[0] + ' ' * (maxWidth-cur_c))else:left = maxWidth - cur_c # 这行一共有几个空格if left % (cur_w-1) == 0: # 空格刚好平均分配ans.append((' '*(left//(cur_w-1))).join(wl))else: # 空格不能平均分配x = left % (cur_w-1) # 多余的空格b = left // (cur_w-1) # 平均每个间隔最少的空格数cans = wl[0]for i in range(x): # 前 x 个间隔空 b + 1 个cans += ' ' * (b+1) + wl[i+1]for i in range(x+1, len(wl)): # 后面的都空 b 个cans += ' ' * b + wl[i]ans.append(cans)cur_c = lcur_w = 1wl = [wd]else:cur_c += lcur_w += 1wl.append(wd)if cur_w > 0: # 所有单词过完了把余下的词放入最后一行cans = ' '.join(wl)cans += ' ' * (maxWidth - len(cans))ans.append(cans)return ans
69.x 的平方根
题目:
实现int sqrt(int x)
函数,计算并返回x的平方根,其中x 是非负整数
由于返回类型是整数,结果只保留整数的部分,小数部分被舍去
实例:
输入: 4
输出: 2
输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去
思路:
牛顿迭代
y = f ( x ) = x 2 − C y = f(x) = x^2 - C y=f(x)=x2−C,其中C表示待求出平方根的那个整数,C的平方就是函数的零点
牛顿迭代的本质是借助泰勒级数,从初始值开始快速向零点逼近
任取一个 x 0 x_0 x0作为初始值,在每一步的迭代中,我们找到函数图像上的点 ( x i , f ( x i ) ) (x_i, f(x_i)) (xi,f(xi)),过该点做一条斜率为该点倒数 f ′ ( x i ) f'(x_i) f′(xi)的直线,与横轴的交点记为 x i + 1 x_{i+1} xi+1, x i + 1 x_{i+1} xi+1相较于 x i x_i xi而言距离零点更接近,在经过多次迭代后,可以得到一个距离零点非常接近的交点,下图是两次迭代得到 x 1 和 x 2 x_1和x_2 x1和x2的过程
选取 x 0 = C x_0 = C x0=C作为初始值
在每一步迭代中,通过当前的交点 x i x_i xi,找到函数图像上的点 ( x i , x i 2 − C ) (x_i, x_i^2-C) (xi,xi2−C),做一条斜率为 f ′ ( x i ) = 2 x i f'(x_i) = 2x_i f′(xi)=2xi的直线,直线方程为:
y l = 2 x i ( x − x i ) + x i 2 − C = 2 x i x − ( x i 2 + C ) yl = 2x_i(x - x_i) + x_i^2 - C = 2x_ix - (x_i^2 + C) yl=2xi(x−xi)+xi2−C=2xix−(xi2+C)
与横轴的交点为方程 2 x i x − ( x i 2 + C ) = 0 2x_ix - (x_i^2 +C) = 0 2xix−(xi2+C)=0的解,即为更新的迭代结果 x i + 1 x_{i+1} xi+1, x i + 1 = 1 2 ( x i + C x i ) x_{i+1} = \frac{1}{2}(x_i+\frac{C}{x_i}) xi+1=21(xi+xiC)
在进行k次迭代后, x k x_k xk的值与真实的零点 C \sqrt{C} C 足够接近,即可作为答案
class Solution:def mySqrt(self, x):if x == 0:return 0C, x0 = float(x), float(x)while True:xi = 0.5 * (x0 + C / x0)if abs(x0 - xi) < 1e-7:breakx0 = xireturn int(x0)
方法二:
二分查找
由于x的平方根的整数部分ans是满足 k 2 < = x k^2 <= x k2<=x的最大k值,可以对k进行二分查找
二分查找的下界为0,上界可以设定为x,在二分查找的每一步中,我们只需要比较中间元素mid的平方与x的大小关系,并通过比较的结果调整上下界的范围
class Solution:def mySqrt(self, x):l, r, ans = 0, x, -1while l <= r:mid = (l + r) // 2if mid * mid <= x:ans = midl = mid + 1else:r = mid - 1return ans
70.爬楼梯
题目:
假设你正在爬楼梯,需要n阶才能到达楼顶
每次你可以爬1或2个台阶,有多少种不同的方法可以爬到楼顶?
实例:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
思路:
其实就是斐波那契数列
class Solution:def climbStairs(self, n):count = 0tmp1 = 0tmp2 = 1ans = 0while count < n :ans = tmp1 + tmp2tmp1 = tmp2tmp2 = anscount += 1return ans
71.简化路径
题目:
以Unix风格给出一个文件的绝对路径,你需要简化它,将其转换为规范路径
在Unix风格的文件系统中,一个点.
,表示当前目录本身,此外,两个点..
,表示将目录切换到上一级(指向父目录),两者都可以是复杂相对路径的组成部分
请注意,返回的规范路径必须始终以斜杠/
开头,并且,两个目录名之间必须只有一个斜杠/
,最后一个目录名(如果存在),不能以/
结尾,此外,规范路径必须是表示绝对路径的最短字符串
实例:
输入:"/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠
输入:"/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级
输入:"/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换
输入:"/a/./b/../../c/"
输出:"/c"
输入:"/a/../../b/../c//.//"
输出:"/c"
输入:"/a//bc/d//././/.."
输出:"/a/b/c"
思路:
把当前目录压入栈中,遇到..
,弹出栈顶,最后返回栈中元素
class Solution:def simplifyPath(self, path):stack = []path = path.split('/')for item in path:if item == '..':if stack:stack.pop()elif item and item != '.':stack.append(item)return '/' + '/'.join(stack)
72.编辑距离
题目:
给你两个单词word1和word2,请你计算出将word1转换成word2所用的最少操作数
可以对一个单词进行如下三种操作:
1.插入一个字符
2.删除一个字符
3.替换一个字符
实例:
输入:word1 = "horse", word2 = "ros"
输出:3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
输入:word1 = "intention", word2 = "execution"
输出:5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')
思路:
动态规划
dp[i][j]
代表word1 到i
位置转换成word2到j
位置需要最少步数
所以,当word1[i] == word2[j], dp[i][j] = dp[i - 1][j - 1]
;
当word1[i] != word2[j], dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1] + 1)
,其中dp[i - 1][j - 1]
表示替换操作,dp[i - 1][j]
表示删除操作,dp[i][j - 1]
表示插入操作
补充:
以 word1 为 “horse”,word2 为 “ros”,且 dp[5][3] 为例,即要将 word1的前 5 个字符转换为 word2的前 3 个字符,也就是将 horse 转换为 ros,因此有:
(1) dp[i-1][j-1],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 2 个字符 ro,然后将第五个字符 word1[4](因为下标基数以 0 开始) 由 e 替换为 s(即替换为 word2 的第三个字符,word2[2])
(2) dp[i][j-1],即先将 word1 的前 5 个字符 horse 转换为 word2 的前 2 个字符 ro,然后在末尾补充一个 s,即插入操作
(3) dp[i-1][j],即先将 word1 的前 4 个字符 hors 转换为 word2 的前 3 个字符 ros,然后删除 word1 的第 5 个字符
注意,针对第一行,第一列要单独考虑,引入''
,如下图所示:
第一行,是word1为空变成word2最少步数,就是插入步数
第一列,是word2为空,需要的最少步数,就是删除操作
# 自底向上
class Solution:def minDistance(self, word1, word2):n1 = len(word1)n2 = len(word2)dp = [[0] * (n2 + 1) for _ in range(n1 + 1)]for j in range(1, n2 + 1):dp[0][j] = dp[0][j - 1] + 1for i in range(1, n1 + 1):dp[i][0] = dp[i - 1][0] + 1for i in range(1, n1 + 1):for j in range(1, n2 + 1):if word1[i - 1] == word2[j - 1]:dp[i][j] = dp[i - 1][j - 1]else:dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1return dp[-1][-1]
73.矩阵置零
题目:
给定一个m x n 的矩阵,如果一个元素为0,则将其所在行和列的所有元素都设为0,请使用原地算法
实例:
输入:
[[1,1,1],[1,0,1],[1,1,1]
]
输出:
[[1,0,1],[0,0,0],[1,0,1]
]
输入:
[[0,1,2,0],[3,4,5,2],[1,3,1,5]
]
输出:
[[0,0,0,0],[0,4,5,0],[0,3,1,0]
]
思路:
1.用 O ( m + n ) O(m + n) O(m+n)额外空间
扫两遍matrix,第一遍用集合记录哪些行,哪些列有0,第二遍置0
class Solution:def setZeroes(self, matrix):row = len(matrix)col = len(matrix[0])row_zero = set()col_zero = set()for i in range(row):for i in range(col):if matrix[i][j] == 0:row_zero.add(i)col_zero.add(j)for i in range(row):for j in range(col):if i in row_zero or j in col_zero:matrix[i][j] = 0
2.用 O ( 1 ) O(1) O(1)空间
用matrix第一行和第一列记录该行该列是否有0作为标志位,但是对于第一行和第一列要设置一个标志位,为了防止自己这一行(一列)也有0的情况
class Solution:def setZeroes(self, matrix):row = len(matrix)col = len(matrix[0])row0_flag = Falsecol0_flag = False# 找第一行是否有0for j in range(col):if matrix[0][j] == 0:row0_flag = Truebreak# 第一列是否有0for i in range(row):if matrix[i][0] == 0:col0_flag = Truebreak# 把第一行或者第一列作为 标志位for i in range(1, row):for j in range(1, col):if matrix[i][j] == 0:matrix[i][0] = matrix[0][j] = 0# 置0for i in range(1, row):for j in range(1, col):if matrix[i][0] == 0 or matrix[0][j] == 0:matrix[i][j] = 0if row0_flag:for j in range(col):matrix[0][j] = 0if col0_flag:for i in range(row):matrix[i][0] = 0
74.搜索二维矩阵
题目:
编写一个高效的算法来判断m x n 矩阵中,是否存在一个目标值,该矩阵有如下特性:
- 每行中的整数从左到右按升序排列
- 每行的第一个整数大于前一行的最后一个整数
实例:
输入:
matrix = [[1, 3, 5, 7],[10, 11, 16, 20],[23, 30, 34, 50]
]
target = 3
输出: true
输入:
matrix = [[1, 3, 5, 7],[10, 11, 16, 20],[23, 30, 34, 50]
]
target = 13
输出: false
# 法一(推荐):从左下角开始查找,如果比当前值大,则去上一行找,如果比当前值小,则向后找
class Solution:def searchMatrix(self, matrix, target):row = len(matrix) - 1col = len(matrix[0]) - 1i = rowj = 0while j <= col and i >= 0 :if target < matrix[i][j]:i -= 1elif target > array[i][j]:j += 1else:return Truereturn False
# 法二:转换成一维数组,然后使用二分查找
class Solution:def searchMatrix(self, matrix, target):if not matrix or not matrix[0]:return Falseleft, right = 0, len(matrix) * len(matrix[0]) - 1array = [column for row in matrix for column in row]while left <= right:mid = ((right - left) >> 1) + leftif array[mid] == target:return Trueelif array[mid] < target:left = mid + 1else:right = mid - 1return False
75.颜色分类
题目:
给定一个包含红色,白色和蓝色,一共n个元素的数组,原地对他们进行排序,使得相同颜色的元素相邻,比男找红色,白色,蓝色的顺序排序
使用0, 1, 2分别表示红色,白色,蓝色
实例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
思路:
三指针
1.定义0的右界bound_0 = 0, 2的左界bound_2 = n - 1,n为数组长度,cur为当前元素
2.当cur <= bound_2时,进入循环
若nums[cur] == 0,此时和0的右界bound_0进行交换,并更新右界和cur,即bound_0 += 1,cur += 1
若nums[cur] == 2,和2的左界bound_2进行交换,并更新左界,向左移动,即bound_2 -= 1
若nums[cur] == 1,则将cur指向下一元素
class Solution:def sortColors(self, nums):n = len(nums)bound_0 = 0bound_2 = n - 1cur = 0while cur <= bound_2:if nums[cur] == 0:nums[cur], nums[bound_0] = nums[bound_0], nums[cur]bound_0 += 1cur += 1elif nums[cur] == 2:nums[cur], nums[bound_2] = nums[bound_2], nums[cur]dound_2 -= 1else:cur += 1
补充:
三色旗问题
假设有一条绳子,上面有红,白,蓝三种颜色的棋子,起初绳子上的棋子颜色并没有顺序,希望将之分类,并排序为蓝,白,红的顺序,要如何移动次数才会最少,(只能在绳子上进行移动,并且一次只能调换两色旗子)
方法一:直接交换蓝旗和红旗的位置,剩下的就是白旗位置
方法二:从绳子开头进行,那么遇到蓝色往前移,遇到白色留在中间,遇到红色后移
'''1.如果w所在的位置为白色,则w+1,表示未处理的部分移至白色群组;2.如果w部分为蓝色,则b与w的元素对调,而b与w必须各+1,表示两个群组都多了一个元素当w指向的是蓝色而要和b的指向交换时,如果b指向的不是蓝色,则交换,否则,如果b指向 的是蓝色,则也没有必要把两个蓝色的旗子交换,这时只需要把b和w都往后移一位3.如果w所在的位置是红色,则将w与r交换,但r要减1,表示未处理的部分减1当w指向的是红色而和r交换时,如果此时r指向的是红色,显然没有必要把两个红色旗子交 换,所以这时应该把r前移,知道r指向的不是红色的时候才和w指向的旗子交换
'''
# 定义三个标识,wFlag和bFlag初始状态为0,表示在开头,rFlag初始为len(color)-1表示在末尾
color = ['R','B','R','W','R','R','W','B','B','W']
wFlag, bFlag, rFlag = 0, 0, len(color) - 1# 当红旗索引小于白旗索引,表示剩下的旗子都是红色,程序结束
while wFlag <= rFlag:if color[wFlag] == 'W':wFlag += 1elif color[wFlag] == 'B':color[bFlag], color[wFlag] = color[wFlag], color[bFlag]bFlag += 1wFlag += 1else:while wFlag < rFlag and color[rFlag] == 'R':rFlag -= 1color[rFlag], clolr[wFlag] = color[wFlag], color[rFlag]rFlag -= 1
76.最小覆盖子串
题目:
给你一个字符串S,一个字符串T,请在字符串S里面找出:包含T所有字符的最小子串
实例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果S中不存在这样的子串,返回''
如果S中存在这样的子串,保证他是唯一答案
思路:
滑动窗口
用i, j表示滑动窗口的左边界和右边界,通过改变i, j来扩展和收缩滑动窗口,可以想象成一个窗口在字符串上游走,当这个窗口包含的元素满足条件,即包含字符串T的所有元素,记录下这个滑动窗口的长度j - i + 1
,这些长度中最小的值就是要求的结果
步骤1:
不断增加j,使滑动窗口增大,知道窗口包含了T的所有元素
步骤2:
不断增加i,使滑动窗口缩小,因为是要求最小字串,所以将不必要的元素排除在外,使长度缩小,直到碰到一个必须包含的元素
步骤3:
让i增加一个位置,这个时候原本的窗口不满足条件,继续执行步骤1,寻找新的满足条件的窗口,如此反复,知道j超出了字符串S的范围
class Solution:def minWindow(self, s, t):need = collections.defaultdict(int)for c in t:need[c] += 1needCnt = len(t)i = 0res = (0, float('inf'))for j, c in enumerate(s):if need[c] > 0:needCnt -= 1need[c] -= 1# 步骤1,滑动窗口包含了所有T元素if needCnt == 0:# 步骤2增加i,排除多余元素while True:c = s[i]if need[c] == 0:breakneed[c] += 1i += 1if j - i < res[1] - res[0]:res = (i, j)# 步骤3,i增加一个位置,寻找新的满足条件滑动窗口need[s[i]] += 1needCnt += 1i += 1return '' if res[1] > len(s) else s[res[0] : res[1]+1]
77.组合
题目:
给定两个整数n和k,返回1…n中所有可能的k个数的组合
实例:
输入: n = 4, k = 2
输出:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],
]
绿色的部分是不能产生结果的分枝
class Solution:def combine(self, n, k):if n <= 0 or k <= 0 or k > n :return []res = []self.__dfs(1, k, n, [], res)return resdef __dfs(self, start, k, n, pre, res):if len(pre) == k:res.append(pre[:])return for i in range(start, n-(k-len(pre))+2):pre.append(i)self.__dfs(i+1, k, n, pre, res)pre.pop()
78.子集
题目:
给定一组不含重复元素的整数数组nums,返回该数组所有可能的子集(幂集)
说明:
解集不能包含重复的子集
实例:
输入: nums = [1,2,3]
输出:
[[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[]
]
# 方法1:递归
class Solution:def subsets(self, nums):res = []n = len(nums)def helper(i, tmp):res.append(tmp)for j in range(i, n):helper(j + 1, tmp + [nums[j]])helper(0, [])return res
# 方法2:内置函数
# product 笛卡尔积(有放回抽样排列)
# permutations 排列(不放回抽样排列)
# combinations 组合,没有重复(不放回抽样组合)
# combinations_with_replacement 组合,有重复(有放回抽样组合)
class Solution:def subsets(self, nums):res = [[],]for i in range(1, len(nums) + 1):for tup in itertools.combinations(nums, i):res.append(list(tup))return res
79.单词搜索
题目:
给定一个二维网格和一个单词,找出该单词是否存在于网格中
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是哪些水平相邻或垂直相邻的单元格,同一个单元格内的字母不允许被重复使用
实例:
board =
[['A','B','C','E'],['S','F','C','S'],['A','D','E','E']
]给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false
class Solution:def exist(self, board, word):if not board:return Falsefor i in range(len(board)):for j in range(len(board[0])):if self.dfs(board, i, j, word):return Truereturn Falsedef dfs(self, board, i, j, word):if len(word) == 0:return Trueif i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or word[0] != board[i][j]:return Falsetmp = board[i][j]board[i][j] = '0'res = self.dfs(board, i+1, j, word[1:]) or self.dfs(board, i-1, j, word[1:]) or self.dfs(board, i, j+1, word[1:]) or self.dfs(board, i, j-1, word[1:])board[i][j] = tmpreturn res
80.删除排序数组中的重复项 II
题目:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度
不要使用额外的数组空间,你必须在原地修改输入数组,并在使用O(1)额外空间的条件下完成
实例:
给定 nums = [1,1,1,2,2,3],函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。你不需要考虑数组中超出新长度后面的元素
给定 nums = [0,0,1,1,1,1,2,3,3],函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。你不需要考虑数组中超出新长度后面的元素
class Solution:def removeDuplicates(self, nums):if not nums:return Nonei = 0# 添加一个标识为flag,如果flag = True则跳过,如果flag = False则移动flag = Falsefor j in range(1, len(nums)):if nums[j] != nums[i]:i += 1nums[i] = nums[j]flag = Falseelse:if not flag:i += 1nums[i] = nums[j]flag = Truereturn i+1
81.搜索旋转排序数组 II
题目:
假设按照升序排序的数组在预先位置的某个点上进行了旋转
例如(数组[0, 0, 1, 2, 2, 5, 6]
可能变为[2, 5, 6, 0, 0, 1, 2]
)
编写一个函数来判断给定的目标值是否存在于数组中,若存在,返回true,否则返回false
实例
输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false
思路:
二分法
1.初始化 l = 0 和右指针r = n - 1
2.循环条件 l <= r
- mid = (l + r) // 2,若nums[mid] == target,返回true
- 若nums[mid] == nums[l] == nums[r],将左右指针同时向里移一位,l += 1, r -= 1
- 若nums[mid] >= nums[l] 说明此时mid在左子列中:
- 若此时nums[l] <= target < nums[mid],说明target在左子列中,则此时令r = mid - 1,否则令l = mid + 1
- 否则,说明mid在右子列中:
- 若nums[mid] < target <= nums[r]说明target在右子列中,则此时令l = mid + 1,否则令r = mid - 1
3.返回False
class solution:def search(self, nums, target):l = 0r = len(nums) - 1while l<=r:mid = (l+r) // 2if nums[mid] == target:return True# l和mid重复,l加一if nums[mid] == nums[l]: l += 1# mid和r重复,r减一elif nums[mid] == nums[r]: r -= 1# l到mid是有序的,判断target是否在其中elif nums[mid] > nums[l]: # target在其中,选择l到mid这段if nums[l] <= target < nums[mid]: r = mid - 1# target不在其中,扔掉l到mid这段else: l = mid + 1# mid到r是有序的,判断target是否在其中elif nums[mid] < nums[r]: if nums[mid] < target <= nums[r]:l = mid + 1else:r = mid - 1 return False
82.删除排序链表中的重复元素 II
题目:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有出现的数字
实例:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
输入: 1->1->1->2->3
输出: 2->3
思路:
快慢指针,用快指针跳过哪些有重复的数字,慢指针负责和快指针拼接
class Solution:def deletteDuplicates(self, head):if head == None or head.next == None:return headdummy = ListNode(-1)dummy.next = headslow = dummyfast = dummy.nextwhile fast:if fast.next and fast.next.val == fast.val:tmp = fast.val# 移动快指针的标准:跳过重复数字while fast and tmp == fast.val:fast = fast.nextelse:slow.next = fastslow = fastfast = fast.nextslow.next = fastreturn dummy.next
83.删除排序链表中的重复元素
题目:
给定一个排序链表,删除所有重复元素,使得每个元素出现一次
实例:
输入: 1->1->2
输出: 1->2
输入: 1->1->2->3->3
输出: 1->2->3
class Solution:def deleteDuplicates(self, head):if head == None or head.next == None:return headdummy_head = ListNode(None)dummy_head.next = headpre = dummy_headcur = headwhile cur:# 在pre存在的情况下,如果当前值和上一个值相等,就跳过当前值,将上一个值的指针直接指向当前值得下一个if pre and cur.val == pre.val:pre.next = cur.next# 将当前值的next指针置为空cur.next = None# 依然保证当前值在pre的下一个位置cur = pre.nextcontinuepre = curcur = cur.nextreturn dummy_head.next
# 递归解法:
'''递归函数返回的不重复子链的头结点,在回溯过程中,比较当前节点和子链头结点的val是否相同,若相同则保留当前节点(删除子链头结点)
'''
class Solution:def deleteDuplicates(self, head):if head is None or head.next is None:return headchild = self.deleteDuplicates(head.next)if child and head.val == child.val:head.next = child.nextchild.next = Nonereturn head
84.柱状图中最大的矩形
题目:
给定n个非负整数,用来表示柱状图中各个柱子的高度,每个柱子彼此相邻,宽为1,求在该柱状图中,能够勾勒出来的矩形的最大面积
实例:
输入: [2,1,5,6,2,3]
输出: 10
思路:
要想找以第i根柱子为最矮柱子所能延伸的最大面积,是以i为中心,向左找第一个小于heights[i]的位置left_i;向右找第一个小于heights[i]的位置right_i,即最大面积为heights[i] * (right_i - left_i - 1)
,
当找i左边第一个小于heights[i]如果heights[i-1] >= heights[i]
其实就是和heights[i-1]
左边第一个小于heights[i-1]
一样
单调栈:
从左到右遍历柱子,对于每一个柱子,我们想找到第一个高度小于它的柱子,那么我们就可以使用一个单调递增栈来实现,如果柱子大于栈顶的柱子,那么说明不是我们要找的柱子,就入栈,继续遍历,如果比栈顶小,那么我们就找到了第一个小于栈顶的柱子
对于栈顶元素,其右边第一个小于它的就是当前遍历到的柱子,左边第一个小于它的就是栈中下一个要被弹出的元素,因此以当前栈顶为最小柱子的面积为当前栈顶的柱子高度 * (当前遍历到的柱子索引 - 1 - 栈中下一个要被弹出的元素索引 - 1 + 1)
class Solution:def largestRectangleArea(self, heights):stack = []# 防止空栈的情况heights = [0] + heights + [0]res = 0for i in range(len(heights)):# 构建单调栈while stack and heights[stack[-1]] > heights[i]:tmp = stack.pop()res = max(res, (i - stack[-1] - 1) * heights[tmp])stack.append(i)return res
补充:
单调栈
设栈顶元素为b,栈顶第二个元素为a,自然有a < b(因为堆栈越往上越大)
这时候,若c出现,且c小于b,那么b的左右第一个比b小的两个元素就找到了,分别是a和c,b在中间最大
这时可以处理b,并重新整理堆栈,使其保持递增
若c大于b,那c入栈,继续循环,最后清理栈
# 单调栈的结构
for i in list:while i is not empyt and stack[-1] > i : # 先调整位置stack.pop()# 当前元素一定会入栈,不同的只是需不需要pop来调整位置stack.append(i)
问题在于:以B点位高的矩形的最大宽度为从a到c,其中a, c分别为B左边和右边第一个小于B的元素
单调栈的特点在于:
当遇见大数的时候,压入堆栈,等待之后处理
当遇见小数c的时候,意味着大数b的右边界c已经确定了,这时候开始pop,而以被pop出来的值(b)为高度的矩形的左右边界需要被确定
其右边界就是当前的小数,即c,左边界是堆栈的下一层元素,因为下一层的元素一定比当前小,且是第一小的元素,这时a确定
则以被pop出来的数为高度的矩形是(c - a - 1)* pop(),这里pop() == b
这里需要注意的是:
1.栈底要垫上 -1,表示栈底
2.循环结束,要清理堆栈,此时所有栈中继续存放的元素的右边界c都是结尾len(height) - 1
85.最大矩形
题目:
给定一个仅包含0和1的二维二进制矩阵,找出只包含1的最大矩形,并返回其面积
实例:
输入:
[["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]
]
输出: 6
思路:
可以转换为上一题的思路:栈
只需要遍历每行的高度,用上一题的方法求出最大矩形
class Solution:def maximalRectangle(self, matrix):if not matrix or not matrix[0]:return 0row = len(matrix)col = len(matrix[0])heights = [0] * (col + 2)res = 0for i in range(row):stack = []for j in range(col):if matrix[i][j] == '1':heights[j+1] += 1else:heights[j+1] = 0for j in range(col + 2):while stack and heights[stack[-1]] > heights[j]:temp = stack.pop()res = max(res, (j - stack[-1] - 1) * heights[temp])stack.append(j)return res
86.分隔链表
题目:
给定一个链表和一个特定值x,对链表进行分隔,使得所有小于x的节点都在大于或等于x的节点之前,应当保留两个分区中每个节点的初始相对位置
实例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
class Solution:def partition(self, head, x):# before, after是用来创建两个链表的两个指针before = before_head = ListNode(0)# before_head, after_head用于保存两个链表的头部after = after_head = ListNode(0)while head:# 如果原始链表节点小于给定的x,将它分配给before链表if head.val < x:before.next = headbefore = before.nextelse: # 如果原始链表节点大于或等于给定的x,将它分配给after链表after.next = headafter = after.nexthead = head.next# after链表的最后一个节点也是经过修改的链表的结束节点after.next = None# 一旦所有的节点都被正确分配到两个链表中,将它们组合返回before.next = after_head.nextreturn before_head.next
87.扰乱字符串
题目:
给定一个字符串s1,我们可以把它递归的分割成两个非空子字符串,从而将其表示为二叉树
great/ \gr eat/ \ / \
g r e at/ \a t
上图是s1 = great
的一种可能的表示形式
在扰乱这个字符串的过程中,我们可以挑选任何一个非叶结点,然后交换它的两个子节点
例如,挑选非叶结点gr
,交换它的两个子节点,将会产生扰乱字符串rgeat
rgeat/ \rg eat/ \ / \
r g e at/ \a t
将rgeat
称作great
的一个扰乱字符串
同样,如果继续交换节点eat
和at
的子节点,将会产生另一个新的扰乱字符串rgtae
rgtae/ \rg tae/ \ / \
r g ta e/ \t a
将rgtae
称作great
的一个扰乱字符串
给出两个长度相等的字符串s1和s2,判断s2是否是s1的扰乱字符串
实例:
输入: s1 = "great", s2 = "rgeat"
输出: true
输入: s1 = "abcde", s2 = "caebd"
输出: false
思路:
递归
S和T如果是扰动的话,那么必然存在一个再S上的长度l1,将S分成S1和S2两段,同样T上也有一个长度l2,把T分为T1和T2
1.如果S1和T1是扰动的,且S2和T2是扰动的,即字符串未交换
2.如果S1和T2是扰动的,且S2和T1是扰动的,即字符串交换了
例如:rgeat和great,rgeat可分成rg和eat两段,great可分成gr和eat两段,rg和gr是扰动的,eat和eat也是扰动的
class Solution:def isScramble(self, s1, s2):if len(s1) != len(s2): return Falseif s1 == s2: return Trueif sorted(s1) != sorted(s2): return Falsefor i in range(1, len(s1)):S1, S2 = s1[:i], s1[i:]T1, T2 = s2[:i], s2[i:]if self.isScramble(S1, T1) and self.isScramble(S2, T2): return TrueT1, T2 = s2[:-i],s2[-i:] # S1、S2不变,更新T1、T2if self.isScramble(S1, T2) and self.isScramble(S2, T1): return Truereturn False
88.合并两个有序数组
题目:
给你两个有序整数数组,nums1和nums2,请你将nums2合并到nums1中,使nums1称为一个有序数组
说明:
- 初始化nums1和nums2的元素量分别为m和n
- 可以假设nums1有足够的空间来保存nums2的元素
实例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3输出: [1,2,2,3,5,6]
class Solution:def merge(self, nums1,m, nums2, n):end = m + n - 1end_1 = m - 1end_2 = n - 1while end_1 >= 0 and end_2 >= 0:if nums1[end_1] >= nums2[end_2]:nums1[end] = nums1[end_1]end_1 -= 1end -= 1else:nums1[end] = nums2[end_2]end_2 -= 1end -= 1nums1[:end_2+1] = nums2[:end_2+1]
89.格雷编码(未解决)
题目:
格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异
给定一个代表编码总位数的非负整数n,打印其格雷编码序列,即使有多个不同答案,你也只需要返回其中的一种
格雷编码序列必须以0开头
实例
输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。00 - 0
10 - 2
11 - 3
01 - 1
输入: 0
输出: [0]
解释: 我们定义格雷编码序列必须以 0 开头。给定编码总位数为 n 的格雷编码序列,其长度为 2n。当 n = 0 时,长度为 20 = 1。因此,当 n = 0 时,其格雷编码序列为 [0]。
90.子集 II
题目:
给定一个可能包含重复元素的整数数组nums,返回该数组所有可能的子集(幂集)
说明:
解集不能包含重复的子集
实例
输入: [1,2,2]
输出:
[[2],[1],[1,2,2],[2,2],[1,2],[]
]
# 递归
class Solution:def subsetsWithDup(self, nums):res = []n = len(nums)nums.sort()def helper(idx, tmp):res.append(tmp)for i in range(idx, n):if i > idx and nums[i] == nums[i-1]:continuehelper(i+1, tmp+[nums[i]])helper(0, [])return res# 迭代
class Solution:def subsetsWithDup(self, nums):if not nums:return []nums.sort()res = [[]]cur = []for i in range(len(nums)):if i > 0 and nums[i-1] == nums[i]:cur = [tmp + [nums[i]] for tmp in cur]else:cur = [tmp + [nums[i]] for tmp in res]res += cur return res
一天一道LeetCode(61-90)相关推荐
- 每日一道leetcode(python)48. 旋转图像
每日一道leetcode(python)48. 旋转图像 2021-07-27 给定一个 n × n 的二维矩阵 matrix 表示一个图像.请你将图像顺时针旋转 90 度. 你必须在 原地 旋转图像 ...
- leetcode17. 电话号码的字母组合--每天刷一道leetcode算法系列!
作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...
- leetcode最小面积_每日一道 LeetCode (51):盛最多水的容器
❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...
- atoi函数_每日一道 LeetCode (50):字符串转换整数 (atoi)
❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...
- 去掉数组最后一个元素_leetcode 34. 在排序数组中查找元素的第一个和最后一个位置每天刷一道leetcode算法系列!...
作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...
- 二叉树层次遍历c语言_每日一道 LeetCode (23):二叉树的层次遍历 II
❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...
- c++两个数组对比去掉重复的元素_每日一道 LeetCode (8):删除排序数组中的重复项和移除元素...
❝ 每天 3 分钟,走上算法的逆袭之路. ❞ 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub:https://github.com/meteor1993/LeetCode Gi ...
- 【python】一道LeetCode搞懂递归算法!#131分割回文串 #以及刷LeetCode的一点点小心得 [数据结构与算法基础]
题目:给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串.返回 s 所有可能的分割方案. # 示例 输入: "aab" 输出: [["aa",&q ...
- 每日一道 LeetCode (16):求 x 的平方根
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...
最新文章
- Clean-Code: 注释
- 广义互相关的公式,这一文都搜集全了
- 使用JavaScript让网页title动起来
- WPF converter(包含传递复杂参数)
- mysql数据库挂科_面试命中率 90% 的点 :MySQL 锁
- flex4 s:Datagrid s:typicalItem
- 复数矩阵分解的拆解思路(矩阵求逆/特征值分解)
- 单片机c语言三种经典程序结构,单片机C语言程序的结构和设计精选.docx
- Ripro子主题-ziyuan-zhankr资源主题 蓝色简约版
- java 90 训练营 二期下载_90天java进阶营二期 主流java技术与热门开源项目视频教程...
- c# 与 c++ 界面同框终极技巧
- weak_ptr概述,weak_ptr常用操作、尺寸
- python之条件判断、循环和字符串格式化
- Log4j2 - java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor
- 30 秒速成好莱坞黑客 -- 在 Linux 终端中伪造好莱坞黑客屏幕
- mysql之获取自增长的ID
- ARTS打卡计划第二周-Algorithm
- ThreeJS 跨域
- Tips--解决Deepin20系统安装完毕无WiFi问题
- 他一生只做一件事,专注150万农场鸡的鸡蛋销售
热门文章
- ios10 NZT10 准备中 预习下iOS10.0-10.2越狱图文教程
- pytorch训练模型常见错误(图像)
- switch语句用法详解
- JAVA毕业设计家教到家平台计算机源码+lw文档+系统+调试部署+数据库
- piaget读法_这些名表的发音 你都读对了吗?(内含音频)
- vue3 watch 和watchEffect()
- ant 是什么???
- VirtualBox设置Ubuntu虚拟机网络通信
- 【数字信号】基于DTMF双音多频电话拨号仿真含Matlab源码
- Advanced-C.07.文件