目录
724. 寻找数组的中心索引
35 搜索插入位置
56. 合并区间
面试题 01.07. 旋转矩阵
面试题 01.08. 零矩阵
498. 对角线遍历
剑指 Offer 66. 构建乘积数组
剑指 Offer 29. 顺时针打印矩阵
剑指 Offer 50. 第一个只出现一次的字符
剑指 Offer 48. 最长不含重复字符的子字符串
209. 长度最小的子数组
剑指 Offer 12. 矩阵中的路径
14. 最长公共前缀
5. 最长回文子串
151. 翻转字符串里的单词
557. 反转字符串中的单词 III
344. 反转字符串
561. 数组拆分 I
167. 两数之和 II - 输入有序数组
27. 移除元素
485. 最大连续1的个数
118. 杨辉三角
119. 杨辉三角 II
283. 移动零
153. 寻找旋转排序数组中的最小值
数据结构与算法
示例 1
示例 2
给定一个整数类型的数组 nums,请编写一个能够返回数组 “中心索引” 的方法。
我们是这样定义数组 中心索引 的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。
示例 1:
输入:
nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
索引 3 (nums[3] = 6) 的左侧数之和 (1 + 7 + 3 = 11),与右侧数之和 (5 + 6 = 11) 相等。
同时, 3 也是第一个符合要求的中心索引。
示例 2:
输入:
nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心索引。
说明:
nums
的长度范围为 [0, 10000]
。nums[i]
将会是一个范围在 [-1000, 1000]
的整数。class Solution:
def pivotIndex(self, nums: List[int]) -> int:
S = sum(nums)
leftsum = 0
for i, x in enumerate(nums):
if leftsum == (S - leftsum - x):
return i
leftsum += x
return -1
作者:LeetCode
链接:https://leetcode-cn.com/problems/find-pivot-index/solution/xun-zhao-shu-zu-de-zhong-xin-suo-yin-by-leetcode/
复杂度分析
时间复杂度:O(N)O(N),其中 NN 是 nums 的长度。
空间复杂度:O(1)O(1),使用了 S 和 leftsum 。
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:输入: [1,3,5,6], 5
输出: 2
示例 2:输入: [1,3,5,6], 2
输出: 1
示例 3:输入: [1,3,5,6], 7
输出: 4
示例 4:输入: [1,3,5,6], 0
输出: 0
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target: left = mid + 1 # insert left side
else: right = mid - 1
return left
难度中等469
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
复杂度分析
时间复杂度:O(nlogn),其中 nn 为区间的数量。除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O(nlogn)。
空间复杂度:O(logn),其中 nn 为区间的数量。这里计算的是存储答案之外,使用的额外空间。O(logn) 即为排序所需要的空间复杂度。
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: x[0])
merged = []
for interval in intervals:
# 如果结果数组是空的,或者当前区间的起始位置 > 结果数组中最后区间的终止位置,
#则不合并,直接将当前区间加入结果数组。
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
# 反之将当前区间合并至结果数组的最后区间
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/merge-intervals/solution/he-bing-qu-jian-by-leetcode-solution/
给你一幅由 N × N
矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?
方法三:用翻转代替旋转 先水平翻转,再主对角线翻转
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
n = len(matrix)
# 水平翻转
for i in range(n // 2):
for j in range(n):
matrix[i][j], matrix[n - i - 1][j] = matrix[n - i - 1][j], matrix[i][j]
# 主对角线翻转
for i in range(n):
for j in range(i):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/rotate-matrix-lcci/solution/xuan-zhuan-ju-zhen-by-leetcode-solution/
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
row_set, col_set = set(), set()
row, col = len(matrix), len(matrix[0])
for i in range(row):
for j in range(col):
if not matrix[i][j]:
row_set.add(i)
col_set.add(j)
for row_idx in row_set:
matrix[row_idx] = [0 for j in range(col)]
for col_idx in col_set:
for i in range(row):
matrix[i][col_idx] = 0
作者:gfu
链接:https://leetcode-cn.com/problems/zero-matrix-lcci/solution/hashsetqu-zhong-by-gfu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
难度中等102
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
class Solution:
def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:
# Check for empty matrices
if not matrix or not matrix[0]:
return []
# Variables to track the size of the matrix
N, M = len(matrix), len(matrix[0])
# The two arrays as explained in the algorithm
result, intermediate = [], []
# We have to go over all the elements in the first
# row and the last column to cover all possible diagonals
for d in range(N + M - 1):
# Clear the intermediate array everytime we start
# to process another diagonal
intermediate.clear()
# We need to figure out the "head" of this diagonal
# The elements in the first row and the last column
# are the respective heads.
r, c = 0 if d < M else d - M + 1, d if d < M else M - 1
# Iterate until one of the indices goes out of scope
# Take note of the index math to go down the diagonal
while r < N and c > -1:
intermediate.append(matrix[r][c])
r += 1
c -= 1
# Reverse even numbered diagonals. The
# article says we have to reverse odd
# numbered articles but here, the numbering
# is starting from 0 :P
if d % 2 == 0:
result.extend(intermediate[::-1])
else:
result.extend(intermediate)
return result
作者:LeetCode
链接:https://leetcode-cn.com/problems/diagonal-traverse/solution/dui-jiao-xian-bian-li-by-leetcode/
给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
示例:
输入: [1,2,3,4,5]
输出: [120,60,40,30,24]
链接:https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof
解法:https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/solution/mian-shi-ti-66-gou-jian-cheng-ji-shu-zu-biao-ge-fe/
class Solution:
def constructArr(self, a: List[int]) -> List[int]:
b, tmp = [1] * len(a), 1
for i in range(1, len(a)):
b[i] = b[i - 1] * a[i - 1] # 下三角
for i in range(len(a) - 2, -1, -1):
tmp *= a[i + 1] # 上三角
b[i] *= tmp # 下三角 * 上三角
return b
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
本题与主站 54 题相同:https://leetcode-cn.com/problems/spiral-matrix/
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
解法二:按层模拟
https://leetcode-cn.com/problems/spiral-matrix/solution/luo-xuan-ju-zhen-by-leetcode-solution/
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not matrix or not matrix[0]:
return list()
rows, columns = len(matrix), len(matrix[0])
order = list()
left, right, top, bottom = 0, columns - 1, 0, rows - 1
while left <= right and top <= bottom:
for column in range(left, right + 1):
order.append(matrix[top][column])
for row in range(top + 1, bottom + 1):
order.append(matrix[row][right])
if left < right and top < bottom:
for column in range(right - 1, left, -1):
order.append(matrix[bottom][column])
for row in range(bottom, top, -1):
order.append(matrix[row][left])
left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1
return order
难度简单
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
解法:链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = {}
for c in s:
dic[c] = not c in dic
for k, v in dic.items():
if v: return k
return ' '
难度中等
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其
长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b"
,所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。
https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/tu-jie-hua-dong-chuang-kou-shuang-zhi-zhen-shi-xia/
复杂度分析
双指针
时间复杂度:O(n^2)。
空间复杂度:O(1),使用了 head,tail,res。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
head = 0
tail = 0
if len(s) < 2: return len(s) # 边界条件
res = 1
while tail < len(s) - 1:
tail += 1
if s[tail] not in s[head: tail]:
res = max(tail - head + 1, res)
else:
while s[tail] in s[head: tail]:
head += 1
return res
解法2:
复杂度分析
时间复杂度:O(n),遍历了一遍 s,哈希表中查找的时间复杂度为 O(1)。
空间复杂度:O(n),使用了哈希表。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
hashmap = {}
head, res = 0, 0
for tail in range(n):
if s[tail] in hashmap:
head = max(hashmap[s[tail]], head)
hashmap[s[tail]] = tail + 1
res = max(res, tail - head + 1)
return res
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。
和剑指 Offer 48. 最长不含重复字符的子字符串思路很像
要注意ans一开始取的值是n+1,超出最长数组范围的最佳选择。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的连续子数组。
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
方法三:双指针
复杂度分析
时间复杂度:O(n),其中 n 是数组的长度。指针start 和 end 最多各移动 n次。
空间复杂度:O(1)。
https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
if not nums:
return 0
n = len(nums)
ans = n + 1
start, end = 0, 0
total = 0
while end < n:
total += nums[end]
while total >= s:
ans = min(ans, end - start + 1)
total -= nums[start]
start += 1
end += 1
return 0 if ans == n + 1 else ans
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum/solution/chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
本题与主站 79 题相同:单词搜索 https://leetcode-cn.com/problems/word-search/
深度优先搜索与回溯详解
from typing import List
class Solution:
# (x-1,y)
# (x,y-1) (x,y) (x,y+1)
# (x+1,y)
directions = [(0, -1), (-1, 0), (0, 1), (1, 0)]
def exist(self, board: List[List[str]], word: str) -> bool:
m = len(board)
if m == 0:
return False
n = len(board[0])
marked = [[False for _ in range(n)] for _ in range(m)]
for i in range(m):
for j in range(n):
# 对每一个格子都从头开始搜索
if self.__search_word(board, word, 0, i, j, marked, m, n):
return True
return False
def __search_word(self, board, word, index,
start_x, start_y, marked, m, n):
# 先写递归终止条件
if index == len(word) - 1:
return board[start_x][start_y] == word[index]
# 中间匹配了,再继续搜索
if board[start_x][start_y] == word[index]:
# 先占住这个位置,搜索不成功的话,要释放掉
marked[start_x][start_y] = True
for direction in self.directions:
new_x = start_x + direction[0]
new_y = start_y + direction[1]
# 注意:如果这一次 search word 成功的话,就返回
if 0 <= new_x < m and 0 <= new_y < n and \
not marked[new_x][new_y] and \
self.__search_word(board, word,
index + 1,
new_x, new_y,
marked, m, n):
return True
marked[start_x][start_y] = False
return False
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/word-search/solution/zai-er-wei-ping-mian-shang-shi-yong-hui-su-fa-pyth/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z
。
简单的横向扫描法:
还有别的解法,查看提交记录
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if not strs:
return ""
prefix, count = strs[0], len(strs)
for i in range(1, count):
prefix = self.lcp(prefix, strs[i])
if not prefix:
break
return prefix
def lcp(self, str1, str2):
length, index = min(len(str1), len(str2)), 0
while index < length and str1[index] == str2[index]:
index += 1
return str1[:index]
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
太难了
给定一个字符串,逐个翻转字符串中的每个单词。
class Solution:
def reverseWords(self, s: str) -> str:
return " ".join(reversed(s.split()))
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string/solution/fan-zhuan-zi-fu-chuan-li-de-dan-ci-by-leetcode-sol/
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii
解题思路
因为在 Python 中字符串是不可变,因此遍历字符串交换每个单词内字符位置的方法不太可行,但是利用 Python 切片的便利,可以写出更优雅的实现方式。
作者:swants
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/solution/python-fan-zhuan-zi-fu-chuan-zhong-dan-ci-si-lu-xi/
三种思路
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
class Solution:
def reverseString(self, s):
s.reverse()
方法二:双指针法
class Solution:
def reverseString(self, s):
left, right = 0, len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left, right = left + 1, right - 1
作者:LeetCode
链接:https://leetcode-cn.com/problems/reverse-string/solution/fan-zhuan-zi-fu-chuan-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
561. 数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:
输入: [1,4,3,2]
输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
题解(Python)
先对给定数列排序(此处为升序);视元素为成对出现,则取数对中的第一个数字即是取出数对中的较小元素(操作中取排序后的数列的所有第奇数个就行);最后求和。
作者:xie-yue-san-xing
链接:https://leetcode-cn.com/problems/array-partition-i/solution/minshu-dui-bi-shi-you-xu-shu-lie-shang-xiang-lin-y/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def arrayPairSum(self, nums: List[int]) -> int:
return sum(sorted(nums)[::2])
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
解题思路
双指针,解题思路见代码注释
class Solution:
def twoSum(self, numbers, target):
#左右指针,i指向左边,j指向右边
i,j = 0,len(numbers)-1
#如果i
该解法与26. 删除排序数组中的重复项的解法十分相似。
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0,1,3,0,4
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
def removeElement(nums, val):
# i为不同元素的数组的长度
i = 0
for j in range(0, len(nums)):
# 如果nums[j]不等于val, 则将nums[j]赋值给nums[i]即可, i自增
if nums[j] != val:
nums[i] = nums[j]
i += 1
return i
作者:leicj
链接:https://leetcode-cn.com/problems/remove-element/solution/python3-yi-chu-yuan-su-by-leicj/
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
方法一:一次遍历
题目的约束让这个问题变得简单,使得我们可以在一次遍历解决它。
算法:
用一个计数器 count 记录 1 的数量,另一个计数器 maxCount 记录当前最大的 1 的数量。
当我们遇到 1 时,count 加一。
当我们遇到 0 时:
将 count 与 maxCount 比较,maxCoiunt 记录较大值。
将 count 设为 0。
返回 maxCount与count的最大值。
作者:LeetCode
链接:https://leetcode-cn.com/problems/max-consecutive-ones/solution/zui-da-lian-xu-1de-ge-shu-by-leetcode/
class Solution:
def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
count = max_count = 0
for num in nums:
if num == 1:
# Increment the count of 1's by one.
count += 1
else:
# Find the maximum till now.
max_count = max(max_count, count)
# Reset count of 1.
count = 0
return max(max_count, count)
作者:LeetCode
链接:https://leetcode-cn.com/problems/max-consecutive-ones/solution/zui-da-lian-xu-1de-ge-shu-by-leetcode/
方法二:忽略
在 Python 中可以使用 map 和 join 来解决此问题。
使用 splits 函数在 0 处分割将数组转换成字符串。
在获取子串的最大长度就是最大连续 1 的长度。
def findMaxConsecutiveOnes(self, nums):
return max(map(len, ''.join(map(str, nums)).split('0')))
作者:LeetCode
链接:https://leetcode-cn.com/problems/max-consecutive-ones/solution/zui-da-lian-xu-1de-ge-shu-by-leetcode/
给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例:
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
动态规划
class Solution:
def generate(self, num_rows):
triangle = []
for row_num in range(num_rows):
# The first and last row elements are always 1.
row = [None for _ in range(row_num+1)]
row[0], row[-1] = 1, 1
# Each triangle element is equal to the sum of the elements
# above-and-to-the-left and above-and-to-the-right.
for j in range(1, len(row)-1):
row[j] = triangle[row_num-1][j-1] + triangle[row_num-1][j]
triangle.append(row)
return triangle
作者:LeetCode
链接:https://leetcode-cn.com/problems/pascals-triangle/solution/yang-hui-san-jiao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
难度简单157收藏分享切换为英文关注反馈
给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例:
输入: 3
输出: [1,3,3,1]
def getRow(self, rowIndex: int) -> List[int]:
tmp = []
for _ in range(rowIndex + 1):
tmp.insert(0, 1)
for i in range(1, len(tmp) - 1):
tmp[i] = tmp[i] + tmp[i+1]
return tmp
作者:powcai
链接:https://leetcode-cn.com/problems/pascals-triangle-ii/solution/mo-ni-guo-cheng-by-powcai-5/
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
说明:
一次遍历
这里参考了快速排序的思想
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
if not nums:
return 0
# 两个指针i和j
j = 0
for i in xrange(len(nums)):
#当前元素等于0的话,先不动,等着后面换到右边。
# 当前元素!=0,就把其交换到左边,等于0的交换到右边
if nums[i]:
nums[j],nums[i] = nums[i],nums[j]
j += 1
作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/move-zeroes/solution/dong-hua-yan-shi-283yi-dong-ling-by-wang_ni_ma/
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。
示例 1:
输入: [3,4,5,1,2]
输出: 1
示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0
在二分搜索的升级了一些
class Solution(object):
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# If the list has just one element then return that element.
if len(nums) == 1:
return nums[0]
# left pointer
left = 0
# right pointer
right = len(nums) - 1
# if the last element is greater than the first element then there is no rotation.
# e.g. 1 < 2 < 3 < 4 < 5 < 7. Already sorted array.
# Hence the smallest element is first element. A[0]
if nums[right] > nums[0]:
return nums[0]
# Binary search way
while right >= left:
# Find the mid element
mid = left + (right - left) / 2
# if the mid element is greater than its next element then mid+1 element is the smallest
# This point would be the point of change. From higher to lower value.
if nums[mid] > nums[mid + 1]:
return nums[mid + 1]
# if the mid element is lesser than its previous element then mid element is the smallest
if nums[mid - 1] > nums[mid]:
return nums[mid]
# if the mid elements value is greater than the 0th element this means
# the least value is still somewhere to the right as we are still dealing with elements greater than nums[0]
if nums[mid] > nums[0]:
left = mid + 1
# if nums[0] is greater than the mid value then this means the smallest value is somewhere to the left
else:
right = mid - 1
作者:LeetCode
链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/solution/xun-zhao-xuan-zhuan-pai-lie-shu-zu-zhong-de-zui-xi/
数据结构是一种数据的表现形式,如链表、二叉树、栈、队列等都是内存中一段数据表现的形式。 算法是一种通用的解决问题的模板或者思路,大部分数据结构都有一套通用的算法模板,所以掌握这些通用的算法模板即可解决各种算法问题。
后面会分专题讲解各种数据结构、基本的算法模板、和一些高级算法模板,每一个专题都有一些经典练习题,完成所有练习的题后,你对数据结构和算法会有新的收获和体会。
先介绍两个算法题,试试感觉~
28. 实现 strStr()
Sunday 解法
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从 0 开始)。如果不存在,则返回 -1。
思路:核心点遍历给定字符串字符,判断以当前字符开头字符串是否等于目标字符串.
78. 子集subsets
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
回溯算法
https://leetcode-cn.com/problems/subsets/solution/hui-su-suan-fa-by-powcai-5/
思路:这是一个典型的应用回溯法的题目,简单来说就是穷尽所有可能性,算法模板如下
通过不停的选择,撤销选择,来穷尽所有可能性,最后将满足条件的结果返回.
面试注意点
我们大多数时候,刷算法题可能都是为了准备面试,所以面试的时候需要注意一些点
快速定位到题目的知识点,找到知识点的通用模板,可能需要根据题目特殊情况做特殊处理。
先去朝一个解决问题的方向!先抛出可行解,而不是最优解!先解决,再优化!
代码的风格要统一,熟悉各类语言的代码规范。
命名尽量简洁明了,尽量不用数字命名如:i1、node1、a1、b2
常见错误总结
访问下标时,不能访问越界
空值 nil 问题 run time error