1
0
mirror of https://github.com/SunnyQjm/algorithm-review.git synced 2026-06-03 08:16:43 +08:00
This commit is contained in:
2020-06-28 16:25:03 +08:00
parent eb8d3279a8
commit 19bc63cf1b
49 changed files with 82 additions and 66 deletions
+1
View File
@@ -24,6 +24,7 @@
#   3. 2 阶 + 1 阶
###############################################################
class Solution:
def climbingStairs(self, n):
"""
-1
View File
@@ -39,7 +39,6 @@ class Solution:
return left - 1
if __name__ == '__main__':
solution = Solution()
print(solution.mySqrt(9))
+3 -2
View File
@@ -1,10 +1,11 @@
#!/usr/bin/env python
# coding=utf-8
class Solution:
################################################
#### 解法一
# 解法一
################################################
def twoSum(self, nums, target):
"""
@@ -19,7 +20,7 @@ class Solution:
return [i, remain.index(target - tmp) + i + 1]
################################################
#### 解法2
# 解法2
################################################
def twoSum2(self, nums, target):
"""
+2 -5
View File
@@ -13,7 +13,7 @@
class Solution:
###################################################
# 此处省略逐字比较,麻烦性能还差,主要是太多难记2333
###################################################
@@ -56,7 +56,7 @@ class Solution:
# 其实这个不是必须的,只是在输入有可能长度不一的情况下,用这个可能可以提高一点性能
if len(s1) != len(s2):
return False
c1 = [0] * 26
c2 = [0] * 26
@@ -73,9 +73,6 @@ class Solution:
return True
if __name__ == '__main__':
solution = Solution()
+5 -5
View File
@@ -29,6 +29,7 @@
import collections
class Solution:
def convert(self, s, numRows):
"""
@@ -49,14 +50,14 @@ class Solution:
if numRows == 1:
return s
lines = [[] for i in range(numRows)]
lines = [[] for i in range(numRows)]
# 当前的方向(首先向下,触底向上,触顶向下,依次改变方向)
goDown = True
# 下一个字符要写入的行号,初始为0,根据方向进行更新,向下则+1,向上则-1
lineNumber = 0
# 依次遍历字符串,按Z字型顺序写到合适的行
for i in range(len(s)):
lines[lineNumber].append(s[i])
@@ -66,7 +67,7 @@ class Solution:
goDown = False
if not goDown and lineNumber == 0:
goDown = True
# 根据当前的方向更新行号
lineNumber = lineNumber + 1 if goDown else lineNumber - 1
@@ -76,7 +77,6 @@ class Solution:
# 将list转字符串返回
return "".join(lines[0])
if __name__ == '__main__':
+3 -4
View File
@@ -23,6 +23,7 @@
from typing import List
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
"""
@@ -40,7 +41,7 @@ class Solution:
# 特判空数组的情况
if len(digits) == 0:
return [1]
needAdd = False
for i in range(len(digits) - 1, -1, -1):
digits[i] += 1
@@ -53,9 +54,8 @@ class Solution:
if needAdd:
digits.insert(0, 1)
return digits
return digits
if __name__ == '__main__':
@@ -66,4 +66,3 @@ if __name__ == '__main__':
print(solution.plusOne([9, 9, 9]), "= [1, 0, 0, 0]")
print(solution.plusOne([9]), "= [1, 0]")
print(solution.plusOne([8, 9, 9, 9]), "= [9, 0, 0, 0]")
+1 -1
View File
@@ -50,6 +50,7 @@
myMap = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
class Solution:
def romanToInt(self, s: str) -> int:
"""
@@ -81,4 +82,3 @@ if __name__ == '__main__':
print(solution.romanToInt("IX"), "= 9")
print(solution.romanToInt("LVIII"), "= 58")
print(solution.romanToInt("MCMXCIV"), "= 1994")
+1 -1
View File
@@ -11,6 +11,7 @@
import math
class Solution:
def mySqrt(self, x):
"""
@@ -63,7 +64,6 @@ class Solution:
return math.floor(next)
if __name__ == '__main__':
solution = Solution()
print(solution.mySqrt(9))
+1 -2
View File
@@ -28,12 +28,11 @@
#################################################################
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{}->{}".format(self.val, repr(self.next))
-1
View File
@@ -67,4 +67,3 @@ if __name__ == '__main__':
print(solution.isValid("(]"), "= False")
print(solution.isValid("([)]"), "= False")
print(solution.isValid("{()}"), "= True")
@@ -47,14 +47,12 @@ class MyQueue:
# 使用两个栈来实现一个队列
self.stack1, self.stack2 = [], []
def push(self, x):
"""
Push element x to the back of queue.
"""
self.stack1.append(x)
def pop(self):
"""
Removes the element from in front of queue and returns that element.
@@ -62,7 +60,6 @@ class MyQueue:
self.peek()
return self.stack2.pop()
def peek(self):
"""
Get the front element.
@@ -72,7 +69,6 @@ class MyQueue:
self.stack2.append(self.stack1.pop())
return self.stack2[-1]
def empty(self):
"""
Returns whether the queue is empty.
-1
View File
@@ -85,4 +85,3 @@ if __name__ == '__main__':
print(solution.isAnagram2("heart", "earth"), " == True")
print(solution.isAnagram2("python", "typhon"), " == True")
print(solution.isAnagram2("qwert", "qwertg"), " == False")
+1
View File
@@ -24,6 +24,7 @@
INT_MAX_VAL = 2147483647
INT_MIN_VAL = -2147483648
class Solution:
def reverse(self, x):
"""
+5 -5
View File
@@ -29,6 +29,7 @@
import collections
class Solution:
def convert(self, s, numRows):
"""
@@ -49,14 +50,14 @@ class Solution:
if numRows == 1:
return s
lines = [[] for i in range(numRows)]
lines = [[] for i in range(numRows)]
# 当前的方向(首先向下,触底向上,触顶向下,依次改变方向)
goDown = True
# 下一个字符要写入的行号,初始为0,根据方向进行更新,向下则+1,向上则-1
lineNumber = 0
# 依次遍历字符串,按Z字型顺序写到合适的行
for i in range(len(s)):
lines[lineNumber].append(s[i])
@@ -66,7 +67,7 @@ class Solution:
goDown = False
if not goDown and lineNumber == 0:
goDown = True
# 根据当前的方向更新行号
lineNumber = lineNumber + 1 if goDown else lineNumber - 1
@@ -76,7 +77,6 @@ class Solution:
# 将list转字符串返回
return "".join(lines[0])
if __name__ == '__main__':
+3 -4
View File
@@ -23,6 +23,7 @@
from typing import List
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
"""
@@ -40,7 +41,7 @@ class Solution:
# 特判空数组的情况
if len(digits) == 0:
return [1]
needAdd = False
for i in range(len(digits) - 1, -1, -1):
digits[i] += 1
@@ -53,9 +54,8 @@ class Solution:
if needAdd:
digits.insert(0, 1)
return digits
return digits
if __name__ == '__main__':
@@ -66,4 +66,3 @@ if __name__ == '__main__':
print(solution.plusOne([9, 9, 9]), "= [1, 0, 0, 0]")
print(solution.plusOne([9]), "= [1, 0]")
print(solution.plusOne([8, 9, 9, 9]), "= [9, 0, 0, 0]")
+1 -1
View File
@@ -50,6 +50,7 @@
myMap = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
class Solution:
def romanToInt(self, s: str) -> int:
"""
@@ -81,4 +82,3 @@ if __name__ == '__main__':
print(solution.romanToInt("IX"), "= 9")
print(solution.romanToInt("LVIII"), "= 58")
print(solution.romanToInt("MCMXCIV"), "= 1994")
+2 -1
View File
@@ -20,11 +20,12 @@ class Stack:
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
class Solution:
def divideBy2(self, decNumber):
"""
+2 -2
View File
@@ -20,7 +20,7 @@ class Queue:
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
@@ -28,6 +28,7 @@ class Queue:
def size(self):
return len(self.items)
class Solution:
def hotPotato(self, nameList, num):
"""
@@ -51,7 +52,6 @@ class Solution:
print(queue.dequeue())
if __name__ == '__main__':
solution = Solution()
solution.hotPotato(["Bill", "David", "Susan", "Jane", "Kent", "Brad"], 7)
+2 -2
View File
@@ -7,6 +7,7 @@
import collections
class Solution:
def palchecker(self, str):
"""
@@ -24,7 +25,7 @@ class Solution:
# 将所有字符入队
for c in str:
dqueue.append(c)
# 依次判断首尾字符是否相同
while len(dqueue) > 1:
if dqueue.pop() != dqueue.popleft():
@@ -38,4 +39,3 @@ if __name__ == '__main__':
print(solution.palchecker("qwertgtrewq"), "= True")
print(solution.palchecker("a"), "= True")
print(solution.palchecker("abcbc"), "= False")
+2 -1
View File
@@ -8,11 +8,12 @@
# 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
###############################################################################
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{}->{}".format(self.val, repr(self.next))
+1 -1
View File
@@ -24,6 +24,7 @@
# 输出: 0
##################################################################################
class Solution:
def searchInsert(self, nums, target):
"""
@@ -55,4 +56,3 @@ if __name__ == '__main__':
print(solution.searchInsert([1, 3, 5, 6], 2), "= 1")
print(solution.searchInsert([1, 3, 5, 6], 7), "= 4")
print(solution.searchInsert([1, 3, 5, 6], 0), "= 0")
+2 -1
View File
@@ -14,7 +14,8 @@
# 输出: 5
##########################################################################
class Solution:
class Solution:
def lengthOfLastWord(self, s):
"""
:type s: str
@@ -20,7 +20,7 @@ class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{}->{}".format(self.val, repr(self.next))
@@ -57,7 +57,7 @@ if __name__ == '__main__':
h1.next = ListNode(1)
h1.next.next = ListNode(2)
print(solution.deleteDuplicates(h1), "= 1->2")
h1 = ListNode(1)
h1.next = ListNode(1)
h1.next.next = ListNode(2)
+1
View File
@@ -20,6 +20,7 @@
# PS: 本题考察异或(^)的理解和使用
######################################################################################
class Solution:
def singleNumber(self, nums):
"""
+1 -1
View File
@@ -35,7 +35,7 @@ class Solution:
if not needle:
return 0
for i in range(0, len(haystack) - len(needle) + 1):
if haystack[i : i + len(needle)] == needle:
if haystack[i: i + len(needle)] == needle:
return i
return -1
+1
View File
@@ -17,6 +17,7 @@
# -10^4 <= target <= 10^4
##############################################################################
class Solution:
def threeSumClosest(self, nums, target):
"""
@@ -16,8 +16,10 @@
# 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
########################################################################################################
class Solution:
numMap = {'2': "abc", '3': "def", '4': "ghi", '5': "jkl", '6': "mno", '7': "pqrs", '8': "tuv", '9': "wxyz"}
def letterCombinations(self, digits):
"""
:type digits: str
@@ -29,6 +31,7 @@ class Solution:
1. 这是一个回溯问题,且没有最优子结构,不能用动态规划,所以可以使用回溯框架用递归方式解决;
回溯框架套路看这里 => https://labuladong.gitbook.io/algo/di-ling-zhang-bi-du-xi-lie/hui-su-suan-fa-xiang-jie-xiu-ding-ban
"""
def _letterCombinations(path, digits, index, result):
"""
:type path: str => 当前路径
@@ -17,15 +17,17 @@
# 你能尝试使用一趟扫描实现吗?
###################################################################################
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{}->{}".format(self.val, repr(self.next))
class Solution:
def removeNthFromEnd(self, head, n):
"""
@@ -51,7 +53,7 @@ class Solution:
while right:
pre, left, right = left, left.next, right.next
if not pre: # 处理要删除的节点是头节点的情况
if not pre: # 处理要删除的节点是头节点的情况
return head.next
else:
pre.next = left.next
+2 -1
View File
@@ -14,6 +14,7 @@
# A1(A2 A3): 10x100x50 + 100x5x50 = 75000
#######################################################################################
class Solution:
def miniMultiplicationTimes(self, matrixs):
"""
@@ -29,7 +30,7 @@ class Solution:
m(i, j) = 0 i <= j <= i + 1
min(i < k < j){m(i, k) + m(k, j) + Pi*Pk*Pj} j > i + 1
"""
# 初始化dp数组
dp = [[float("inf") for i in range(len(matrixs))] for i in range(len(matrixs))]
+1
View File
@@ -18,6 +18,7 @@
# 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
#######################################################################################
class Solution:
def merge(self, intervals):
"""
+1
View File
@@ -15,6 +15,7 @@
# 输出: -1->0->3->4->5
#######################################################################################
class ListNode:
def __init__(self, x):
self.val = x
+1
View File
@@ -15,6 +15,7 @@
# 由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。
#######################################################################################
class Solution:
def hIndex(self, citations):
"""
@@ -27,6 +27,7 @@
# 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
#######################################################################################
class Solution:
def maxProfit(self, prices):
"""
@@ -40,11 +41,11 @@ class Solution:
- 如果第二天比当天高,则当天买入,第二天卖出;
- 如果第二天比当天低,则不操作;
"""
proft = 0
profit = 0
for i in range(len(prices) - 1):
if prices[i + 1] > prices[i]:
proft += (prices[i + 1] - prices[i])
return proft
profit += (prices[i + 1] - prices[i])
return profit
if __name__ == '__main__':
+1
View File
@@ -23,6 +23,7 @@
# 解释: 14 不是丑数,因为它包含了另外一个质因数 7。
#######################################################################################
class Solution:
def isUgly(self, num):
"""
+1
View File
@@ -18,6 +18,7 @@
# PS: PPT中关于凑零钱的问题和这题Leetcode类似,且本题比PPT上更通用
#######################################################################################
class Solution:
def coinChange(self, coins, amount):
"""
+1
View File
@@ -22,6 +22,7 @@
# 输出: 28
#######################################################################################
class Solution:
def uniquePaths(self, m, n):
"""
+1 -1
View File
@@ -27,6 +27,7 @@
# 2. 向下 -> 向下 -> 向右 -> 向右
#######################################################################################
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid):
"""
@@ -63,4 +64,3 @@ class Solution:
if __name__ == '__main__':
solution = Solution()
print(solution.uniquePathsWithObstacles([[0, 0, 0], [0, 1, 0], [0, 0, 0]]), "= 2")
@@ -16,6 +16,7 @@
# 输出: "bb"
#######################################################################################
class Solution:
def longestPalindrome(self, s):
"""
+1
View File
@@ -18,6 +18,7 @@
# 解释: 因为路径 1->3->1->1->1 的总和最小。
#######################################################################################
class Solution:
def minPathSum(self, grid):
"""
+1
View File
@@ -20,6 +20,7 @@
# 如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
#######################################################################################
class Solution:
def minimumTotal(self, triangle):
"""
@@ -27,6 +27,7 @@
# 解释: 在这个情况下, 没有交易完成, 所以最大利润为 0。
#######################################################################################
class Solution:
def maxProfit(self, prices):
"""
@@ -82,4 +83,3 @@ if __name__ == '__main__':
print(solution.maxProfit([3, 3, 5, 0, 0, 3, 1, 4]), "= 6")
print(solution.maxProfit([1, 2, 3, 4, 5]), "= 4")
print(solution.maxProfit([7, 6, 4, 3, 1]), "= 0")
+2 -2
View File
@@ -18,6 +18,7 @@
# 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
#######################################################################################
class Solution:
def lengthOfLIS(self, nums):
"""
@@ -37,7 +38,7 @@ class Solution:
if not nums:
return 0
length = len(nums)
dp, result = [1 for i in range(length)], 1
dp = [1 for i in range(length)]
for i in range(length - 2, -1, -1):
for j in range(i + 1, length):
@@ -49,4 +50,3 @@ class Solution:
if __name__ == '__main__':
solution = Solution()
print(solution.lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18]), "= 4")
+2 -2
View File
@@ -15,6 +15,7 @@
# 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
#######################################################################################
class Solution:
def maxSubArray(self, nums):
"""
@@ -31,11 +32,10 @@ class Solution:
max{f(i - 1) + nums[i], nums[i]} i > 0
"""
for i in range(1, len(nums)):
nums[i] = max(nums[i-1] + nums[i], nums[i])
nums[i] = max(nums[i - 1] + nums[i], nums[i])
return max(nums)
if __name__ == '__main__':
solution = Solution()
print(solution.maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4]), "= 6")
+1 -1
View File
@@ -25,6 +25,7 @@
# 解释:两个字符串没有公共子序列,返回 0。
#######################################################################################
class Solution:
def longestCommonSubsequence(self, text1, text2):
"""
@@ -64,4 +65,3 @@ if __name__ == '__main__':
print(solution.longestCommonSubsequence("abcde", "ace"), "\n= 3")
print(solution.longestCommonSubsequence("abc", "abc"), "\n= 3")
print(solution.longestCommonSubsequence("abc", "def"), "\n= 0")
+2 -2
View File
@@ -6,9 +6,10 @@
#
# 给你一个可装载重量为 W 的背包和 N 个物品,每个物品有重量和价值两个属性。其中第 i 个
# 物品的重量为wt[i],价值为 val[i],现在让你用这个背包装物品,最多能装的价值是多少?
#
#######################################################################################
class Solution:
def knapsack(self, W, N, wt, val):
"""
@@ -42,4 +43,3 @@ class Solution:
if __name__ == '__main__':
solution = Solution()
print(solution.knapsack(4, 3, [2, 1, 3], [4, 2, 3]), "= 6")
+1
View File
@@ -8,6 +8,7 @@
# 的效益,i=1,…, n. 问:如何分配这m元钱,使得投资的总效益最高?
#######################################################################################
class Solution:
def investmentProblem(self, f, m):
"""
+1
View File
@@ -23,6 +23,7 @@
# 2. 每一个 cost[i] 将会是一个Integer类型,范围为 [0, 999]。
#######################################################################################
class Solution:
def minCostClimbingStairs(self, cost):
"""
+2 -1
View File
@@ -29,6 +29,7 @@
# exection -> execution (插入 'u')
#######################################################################################
class Solution:
def minDistance(self, word1, word2):
"""
@@ -47,7 +48,7 @@ class Solution:
f(i, j) = j i == 0
i j == 0
f(i - 1, j - 1) i > 0 && j > 0 && word1[i] == word2[j]
min { i > 0 && j > 0 && word1[i] != word2[j]
min { i > 0 && j > 0 && word1[i] != word2[j]
f(i - 1, j) + 1,
f(i, j - 1) + 1,
f(i - 1, j - 1) + 1
+4 -2
View File
@@ -21,6 +21,7 @@
# coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
#######################################################################################
class Solution:
def maxCoins(self, nums):
"""
@@ -39,7 +40,7 @@ class Solution:
min{f(i, k) + f(k, j) + nums[i] * nums[k] * nums[j] | i < k < j} j > i + 1
如何确定遍历顺序呢?
tip:参考 => https://labuladong.gitbook.io/algo/dong-tai-gui-hua-xi-lie/za-qi-qiu
"""
@@ -54,7 +55,8 @@ class Solution:
for i in range(2, length + 2):
for j in range(0, length + 2 - i):
dp[j][j + i] = max((dp[j][k] + dp[k][j + i] + nums[j] * nums[k] * nums[j + i]) for k in range(j + 1, j + i))
dp[j][j + i] = max(
(dp[j][k] + dp[k][j + i] + nums[j] * nums[k] * nums[j + i]) for k in range(j + 1, j + i))
return dp[0][-1]