coding_v3

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

LeetCode 75 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

数组/字符串

1.LC88【合并两个有序数组】

def solve(nums1, m, nums2, n):
    p1, p2 = m-1, n-1
    tail = m + n -1
    while p1 >= 0 or p2 >= 0:
        if p1 == -1:
            nums1[tail] = nums2[p2]
            p2 -= 1
        elif p2 == -1:
            nums1[tail] = nums1[p1]
            p1 -= 1
        elif nums1[p1] > nums2[p2]:
            nums1[tail] = nums1[p1]
            p1 -= 1
        else:
            nums1[tail] = nums2[p2]
            p2 -= 1
        tail -= 1

2、LC27【原地移除指定元素】

# 原地删除元素指定值
def solve(nums, val):
    n = len(nums)
    left = 0
    for i in range(n):
        if nums[i] != val:
            nums[left] = nums[i]
            left += 1
    return left

3、LC26【原地删除有序数组重复元素】

# 原地删除数组重复元素
def solve(nums):
    n = len(nums)
    left, right = 1, 1
    while right < n:
        if nums[right] != nums[right-1]:
            nums[left] = nums[right]
            left += 1
        right += 1
    return left

4、LC80【原地删除有序数组重复元素2】

# 原地删除数组重复元素【超过两个的元素只保留两个】
def solve(nums):
    n = len(nums)
    left, right = 2, 2
    while right < n:
        if nums[right] != nums[left-2]:
            nums[left] = nums[right]
            left += 1
        right += 1
    return left

5、LC1768【交替合并字符串】

# 交替合并字符串
def solve(word1, word2):
    m, n = len(word1), len(word2)
    p, q = 0, 0
    res = []
    while p < m or q < n:
        if p < m:
            res.append(word1[p])
            p += 1
        if q < n:
            res.append(word2[q])
            q += 1
    return ''.join(res)

6、LC1071【字符串最大公因子】

# 字符串的最大公因子
import math
def solve(str1, str2):
    res_len = math.gcd(len(str1), len(str2))
    if str1[:res_len] * (len(str1) // res_len) == str1 and str1[:res_len] * (len(str2) // res_len) == str2:
        return str1[:res_len]
    return ''

7、LC605【种花问题】

# 种花
def solve(flowerbed, n):
    i = 0
    m = len(flowerbed)
    while i < m:
        if (flowerbed[i] == 0) and (i==0 or flowerbed[i-1] == 0) and (i==m-1 or flowerbed[i+1] == 0):
            i += 2
            n -= 1
        else:
            i += 1
    return n <= 0

8、LC345【翻转字符串中的元音字母】

# 翻转元音字母
def solve(s):
    n = len(s)
    lst = list(s)
    i, j = 0, n-1
    while i < j:
        while i < n and not judge(lst[i]):
            i += 1
        while j > 0 and not judge(lst[j]):
            j -= 1
        if i < j:
            lst[i], lst[j] = lst[j], lst[i]
            i += 1
            j -= 1
    return ''.join(lst)

def judge(item):
    if item in ('a','e','i','o','u','A','E','I','O','U'):
        return 1
    else:
        return 0

9、LC151【翻转字符串中的单词】

# 翻转单词
def solve(s):
    s = s.strip()
    n = len(s)
    i, j = n-1, n-1
    res = []
    while i >= 0:
        while i >= 0 and s[i] != ' ':
            i -= 1
        res.append(s[i+1:j+1])
        while i >= 0 and s[i] == ' ':
            i -= 1
        j = i
    return ' '.join(res)

10、LC238【除自身以外的乘积】

# 除自身以外的数组乘积
def solve(nums):
    ans = [1] * len(nums)
    # 元素左半部分乘积
    for i in range(1, len(nums)):
        ans[i] = ans[i-1] * nums[i-1]
    # 元素右半部分乘积
    ans1 = [1] * len(nums)
    for i in range(len(nums)-2,-1,-1):
        ans1[i] = ans1[i+1] * nums[i+1]
    res = [ans[i] * ans1[i] for i in range(len(ans))]
    return res
        
    

11、LC334【递增三元子序列】

# 递增的三元子序列
def solve(nums):
    n = len(nums)
    if n < 3:
        return False
    small, mid = nums[0], float('inf')
    for i in range(n):
        if nums[i] > mid:
            return True
        if nums[i] > small:
            mid = nums[i]
        else:
            small = nums[i]
    return False

12、LC443【压缩字符串】

# 压缩字符串
def solve(chars):
    def reverse(left, right):
        while left < right:
            chars[left], chars[right] = chars[right], chars[left]
            left += 1
            right -= 1
            
    left, write = 0, 0
    n = len(chars)
    for i in range(n):
        if i == n-1 or chars[i] != chars[i+1]:
            chars[write] = chars[i]
            write += 1
            nums = i - left + 1
            if nums > 1:
                anchor = write
                while nums > 0:
                    chars[write] = str(nums % 10)
                    write += 1
                    nums //= 10
                reverse(anchor, write-1)
            left = i + 1
    return write, chars[:write]

13、LC55【跳跃游戏】

# 跳跃游戏
def solve(nums):
    n = len(nums)
    most = 0
    for i in range(n):
        if i <= most:
            most = max(most, i + nums[i])
            if most >= n - 1:
                return True
    return False

双指针

1、LC283【移动零】

# 移动0
def solve(nums):
    i = 0
    for j in range(len(nums)):
        if nums[j]:
            nums[i], nums[j] = nums[j], nums[i]
            i += 1

2、LC392【判断子序列】

# 判断子序列
def solve(s, t):
    if not s:
        return True
    i = 0
    for c in t:
        if s[i] == c:
            i += 1
            if i == len(s):
                return True
    return False

3、LC11【盛水最多的容器】

# 盛最多水的容器
def solve(height):
    i, j = 0, len(height)-1
    res = 0
    while i < j:
        if height[i] < height[j]:
            res = max(res, height[i] * (j-i))
            i += 1
        else:
            res = max(res, height[j] * (j-i))
            j -= 1
    return res

4、LC167【两数之和 有序数组】

# 两数之和2 有序数组
def solve(nums, target):
    left, right = 0, len(nums) - 1
    while left < right:
        total = nums[left] + nums[right]
        if total == target:
            return [left + 1, right + 1]
        elif total < target:
            left += 1
        else:
            right -= 1
    return [-1, -1]

滑动窗口

1、LC643【子数组最大平均数】

# 子数组的最大平均数
def solve(nums,k):
    res = total = sum(nums[:k])
    for i in range(k,len(nums)):
        total = total-nums[i-k]+nums[i]
        res = max(res, total)
    return res / k

2、LC1456【定长子串中元音的数目】

# 定长字串中元音最大数目
def solve(s, k):
    def judge(ch):
        return int(ch in 'aeiou')
    n = len(s)
    start = 0
    for i in range(k):
        start += judge(s[i])
    res = start
    for i in range(k,n):
        start += judge(s[i]) - judge(s[i-k])
        res = max(res, start)
    return res

3、LC1004【最大连续1的个数】

# 最大连续1的个数
def solve(nums, k):
    n = len(nums)
    res = zeros = 0
    left = right = 0
    while right < n:
        if nums[right] == 0:
            zeros += 1
        while zeros > k:
            if nums[left] == 0:
                zeros -= 1
            left += 1
        res = max(res, right-left+1)
        right += 1
    return res

4、LC1493【删除一个元素后全为1的最长子数组】

# 删除一个元素后全为1的最长子数组
def solve(nums):
    ans = 0
    p0 = p1 = 0
    for i in range(len(nums)):
        if nums[i] == 0:
            p1, p0 = p0, 0
        else:
            p0 += 1
            p1 += 1
        ans = max(ans, p1)
    if ans == len(nums):
        ans -= 1
    return ans

5、LC209【长度最小的子数组】

# 长度最小的子数组
def solve(target, nums):
    left, right = 0, 0
    ans = len(nums) + 1
    total = 0
    while right < len(nums):
        total += nums[right]
        while  total >= target:
            ans = min(ans, right - left + 1)
            total -= nums[left]
            left += 1
        right += 1
    if ans == len(nums) + 1:
        return 0
    else:
        return ans
    

6、LC3【无重复字符的最长子串】

# 无重复字符的最长子串
def solve(s):
    dic = {}
    res = 0
    i = -1
    for j in range(len(s)):
        if s[j] in dic:
            i = max(dic[s[j]], i)
        dic[s[j]] = j
        res = max(res, j - i)
    return res

前缀和

1、LC1732【找到最高海拔】

# 找到最高海拔
def solve(gain):
    ans = total = 0
    for each in gain:
        total += gain
        ans = max(ans, total)
    return ans

2、LC724【寻找数组的中心下标】

# 寻找数组的中心下标
def solve(nums):
    left, right = 0, sum(nums)
    for i in range(len(nums)):
        right -= nums[i]
        if left == right:
            return i
        left += nums[i]
    return -1

哈希表、哈希集合

1、LC2215【找出两数组的不同】

# 找出两数组的不同
def solve(nums1, nums2):
    set1 = set(nums1)
    set2 = set(nums2)
    res1 = []
    res2 = []
    for each in set1:
        if each not in set2:
            res1.append(each)
    for each in set2:
        if each not in set1:
            res2.append(each)
    return [res1, res2]

2、LC1207【独一无二的出现次数】

# 独一无二的出现次数
def solve(arr):
    dic = {}
    for each in arr:
        if each in dic:
            dic[each] += 1
        else:
            dic[each] = 1
    res = list(dic.values())
    return len(res) == len(set(res))

3、LC1657【确定两个字符串是否接近】

# 两个字符串是否接近
def solve(word1, word2):
    c1 = [0] * 26
    c2 = [0] * 26
    for each in word1:
        c1[ord(each)-ord('a')] += 1
    for each in word2:
        c2[ord(each)-ord('a')] += 1
    for i in range(26):
        if c1[i] + c2[i] == 0:
            continue
        if c1[i] == 0 or c2[i] == 0:
            return False
    c1.sort()
    c2.sort()
    for i in range(26):
        if c1[i] != c2[i]:
            return False
    return True

4、LC2352【相等行列对】

# 相等行列对
def solve(grid):
    m, n = len(grid), len(grid[0])
    grid_col = [[0] * m for _ in range(n)]
    for i, g in enumerate(grid):
        for j, x in enumerate(g):
            grid_col[j][i] = x
    res = 0
    for each in grid:
        for ee in grid_col:
            if each == ee:
                res += 1
    return res

1、LC2390【从字符串中移除星号】

# 从字符串中移除星号
def solve(s):
    stack = []
    for each in s:
        if each == '*':
            stack.pop()
        else:
            stack.append(each)
    return ''.join(stack)

2、LC735【小行星碰撞】

# 小行星碰撞
def solve(asteroids):
    stk = []
    for t in asteroids:
        ok = True
        while ok and stk and stk[-1] > 0 and t < 0:
            a, b = stk[-1], -t
            if a <= b:
                stk.pop(-1)
            if a >= b:
                ok = False
        if ok:
            stk.append(t)
    return stk

3、LC394【字符串解码】

# 字符串解码
def solve(s):
    stk = []
    res = ''
    multi = 0
    for each in s:
        if each == '[':
            stk.append([multi, res])
            multi = 0
            res = ''
        elif each == ']':
            cur_multi, cur_res = stk.pop()
            res = cur_res + cur_multi * res
        elif each >= '0' and each <= '9':
            multi = multi * 10 + int(each)
        else:
            res += each
    return res

队列

1、LC649【Dota2 参议院】

# 参议院
def solve(senate):
    n = len(senate)
    r = collections.deque()
    d = collections.deque()
    for i, c in enumerate(senate):
        if c == 'R':
            r.append(i)
        if c == 'D':
            d.append(i)
    while r and d:
        if r[0] < d[0]:
            r.append(r[0]+n)
        else:
            d.append(d[0]+n)
        r.popleft()
        d.popleft()
    return 'Radiant' if r else 'Dire'

链表

1、LC2095【删除链表的中间节点】

# 删除链表的中间节点
def solve(head):
    if head.next is None:
        return None
    slow, fast, pre = head, head, None
    while fast and fast.next:
        pre = slow
        slow = slow.next
        fast = fast.next.next
    pre.next = slow.next
    return head

2、LC328【奇偶链表】

# 奇偶链表
def solve(head):
    if not head:
        return head
    evenHead = head.next
    odd, even = head, evenHead
    while even and even.next:
        odd.next = even.next
        odd = odd.next
        even.next = odd.next
        even = even.next
    odd.next = evenHead
    return head

3、LC206【反转链表】

# 反转链表
def solve(head):
    cur, pre = head, None
    while cur:
        tmp = cur.next
        cur.next = pre
        pre = cur
        cur = tmp
    return pre

4、LC2130【链表最大孪生和】

# 链表最大孪生和
def solve(head):
    # 快慢指针找中点
    slow, fast = head, head.next
    while fast.next:
        slow = slow.next
        fast = fast.next.next
    # 反转后半部分链表
    cur, pre = slow.next, None
    while cur:
        tmp = cur.next
        cur.next = pre
        pre = cur
        cur = tmp
    # 取head和pre的值求和
    res = 0
    while pre:
        cur_res = head.val + pre.val
        res = max(cur_res, res)
        head = head.next
        pre = pre.next
    return res

5、字符串转链表

# 字符串转链表
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
        
def solve(s):
    prehead = ListNode(-1)
    prev = prehead
    for each in s:
        prev.next = ListNode(each)
        prev = prev.next
    return prehead.next

二叉树

0、二叉树定义

# 二叉树
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
        
node1 = TreeNode(2)
node2 = TreeNode(5)
node3 = TreeNode(7)
node4 = TreeNode(9)


node1.left = node2
node1.right = node3

1、LC104【二叉树的最大深度】

深度优先

# 深度优先
def solve(root):
    if not root:
        return 0
    return max(solve(root.left), solve(root.right)) + 1

广度优先

# 广度优先
def solve(root):
    if not root:
        return 0
    quene = [root]
    res = 0
    while quene:
        tmp = []
        for node in quene:
            if node.left:
                tmp.append(node.left)
            if node.right:
                tmp.append(node.right)
        quene = tmp
        res += 1
    return res
    

2、LC872【叶子相似的树】

深度优先

# 叶子相似的树
def solve(root1, root2):
    def dfs(node):
        if not node.left and not node.right:
            return [node.val]
        elif node.left and not node.right:
            return dfs(node.left)
        elif not node.left and node.right:
            return dfs(node.right)
        else:
            return dfs(node.left) + dfs(node.right)
    return dfs(root1) == dfs(root2)

3、LC1448【统计二叉树中好节点的数目】

#统计二叉树中好节点的数目
def solve(root):
    def dfs(root, value):
        if not root:
            return 0
        res = 0
        if root.val >= value:
            res += 1
            value = root.val
        res += dfs(root.left, value) + dfs(root.right, value)
        return res
    return dfs(root, -10**9)

4、LC112【路径总和1】

深度优先

# 深度优先
def solve(root, targetSum):
    if not root:
        return False
    if not root.left and not root.right:
        return root.val == targetSum
    return solve(root.left, targetSum-root.val) or solve(root.right, targetSum-root.val)

广度优先

def solve(root, tagetSum):
    if not root:
        return False
    quene_node = [root]
    quene_val = [root.val]
    while quene_node:
        tmp_node = quene_node.pop(0)
        tmp_val = quene_val.pop(0)
        if not tmp_node.left and not tmp_node.right:
            if tmp_val == targetSum:
                return True
            continue
        if tmp_node.left:
            quene_node.append(tmp_node.left)
            quene_val.append(tmp_val + tmp_node.left.val)
        if tmp_node.right:
            quene_node.append(tmp_node.right)
            quene_val.append(tmp_val + tmp_node.right.val)
    return False

5、LC113【路径总和2】

回溯

# 路径总和2
# 回溯
def solve(root, targetSum):
    res, path = [], []
    def back(root, target):
        if not root:
            return
        path.append(root.val)
        target -= root.val
        if target == 0 and not root.left and not root.right:
            res.append(path)
        back(root.left, target)
        back(root.right, target)
        path.pop()
    back(root, targetSum)
    return res
        

6、LC437【路径总和3】

深度优先

# 路径总和3
# 深度优先
def solve(root, targetSum):
    if not root:
        return 0
    def kernel(root, targetSum):
        if not root:
            return 0
        res = 0
        if root.val == targetSum:
            res += 1
        res += kernel(root.left, targetSum - root.val)
        res += kernel(root.right, targetSum - root.val)
        return res
    res = kernel(root, targetSum)
    res += solve(root.left, targetSum)
    res += solve(root.right, targetSum)
    return res

7、LC1372【二叉树的最长交错路径】

深度优先

# 二叉树的最长交错路径
def solve(root):
    res = 0
    def dfs(root, direction, length):
        if not root:
            return
        nonlocal res
        res = max(res, length)
        if direction == 0:
            dfs(root.left, 1, length+1)
            dfs(root.right, 0, 1)
        if direction == 1:
            dfs(root.right, 0, length+1)
            dfs(root.left, 1, 1)
    dfs(root, 0, 0)
    dfs(root, 1, 0)
    return res

8、二叉树的最近公共祖先

深度优先

# 二叉树的最近公共祖先
def solve(root, p, q):
    if not root or root == p or root == q:
        return root
    left = solve(root.left, p, q)
    right = solve(root.right, p, q)
    if not left:
        return right
    if not right:
        return left
    return root

二叉树广度优先

1、LC199【二叉树的右视图】

# 二叉树的右视图
def solve(root):
    depth = dict()
    max_depth = -1
    quene = [(root, 0)]
    while quene:
        node, cur_depth = quene.pop(0)
        if node:
            max_depth = max(max_depth, cur_depth)
            depth[cur_depth] = node.val
            quene.append((node.left, cur_depth+1))
            quene.append((node.right, cur_depth+1))
    res = []
    for each in range(max_depth+1):
        res.append(depth[each])
    return res
    

2、LC1161【最大层内元素和】

# 最大层内元素和
def solve(root):
    ans, num, quene, level = 1, -inf, [root], 1
    while quene:
        cur = 0
        for i in range(len(quene)):
            node = quene.pop(0)
            cur += node.val
            if node.left:
                quene.append(node.left)
            if node.right:
                quene.append(node.right)
        if cur > num:
            ans = level
            num = cur
        level += 1
    return ans

3、LC700【二叉搜索树中的搜索】

# 二叉搜索树中的搜索
def solve(root, val):
    if not root:
        return None
    while root:
        if root.val == val:
            return root
        root = root.right if root.val < val else root.left
    return None

4、LC450【删除二叉搜索树中的节点】

# 删除二叉搜索树中的节点
def solve(root, key):
    if not root:
        return None
    if key > root.val:
        root.right = self.solve(root.right, key)
    elif key < root.val:
        root.left = self.solve(root.left, key)
    else:
        if not root.right:
            return root.left
        elif not root.left:
            return root.right
        elif root.right and root.left:
            tmp = root.right
            while tmp.left:
                tmp = tmp.left
            tmp.left = root.left
            root = root.right
    return root

图-深度优先

1、LC841【钥匙和房间】

深度优先

# 钥匙和房间
# 深度优先
def solve(rooms):
    n = len(rooms)
    visit = set()
    num = 0
    def dfs(x):
        visit.add(x)
        nonlocal num
        num += 1
        for each in rooms[x]:
            if each not in visit:
                dfs(each)
    dfs(0)
    return num == n

广度优先

# 广度优先
def solve(rooms):
    n = len(rooms)
    num = 0
    visit = {0}
    quene = [0]
    while quene:
        x = quene.pop(0)
        num += 1
        for each in rooms[x]:
            if each not in visit:
                visit.add(each)
                quene.append(each)
    return num == n

2、LC547【省份数量】

深度优先

# 省份数量
# 深度优先
def solve(isConnected):
    n = len(isConnected)
    visit = set()
    res = 0
    def dfs(i):
        for j in range(n):
            if isConnected[i][j] == 1 and j not in visit:
                visit.add(j)
                dfs(j)
    for i in range(n):
        if i not in visit:
            dfs(i)
            res += 1
    return res

广度优先

# 广度优先
def solve(isConnected):
    n = len(isConnected)
    res = 0
    visit = set()
    for i in range(n):
        if i not in visit:
            quene = [i]
            while quene:
                j = quene.pop(0)
                visit.add(j)
                for k in range(n):
                    if isConnected[j][k] == 1 and k not in visit:
                        quene.append(k)
            res += 1
    return res

图-广度优先

1、LC1926【迷宫中离入口最近的出口】

# 迷宫中离入口最近的出口
import collections
def solve(maze, entrance):
    m, n = len(maze), len(maze[0])
#     print(m,n)
    quene = collections.deque([(entrance[0], entrance[1], 0)])
    maze[entrance[0]][entrance[1]] = '+'
    while quene:
#         print(quene)
#         break
        x, y, d = quene.popleft()
#         print(x,y,d)
        for nx, ny in [(x+1,y),(x,y+1),(x-1,y),(x,y-1)]:
#             print(nx,ny)
            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == '.':
                if nx == 0 or nx == m - 1 or ny == 0 or ny == n - 1:
                    return d + 1
                maze[nx][ny] = '+'
                quene.append((nx, ny, d+1))
#                 print(quene)
#                 break
    return -1  

2、LC994【腐烂的橘子】

#腐烂的橘子
def solve(grid):
    m, n = len(grid), len(grid[0])
    count = 0 # 新鲜橘子的数量
    quene = []
    for i in range(m):
        for j in range(n):
            if grid[i][j] == 1:
                count += 1
            elif grid[i][j] == 2:
                quene.append((i, j))
    res = 0
    while count > 0 and quene:
        res += 1
        for i in range(len(quene)):
            x, y = quene.pop(0)
            for nx, ny in [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]:
                if 0 <= nx and nx < m and 0 <= ny and ny < n:
                    if grid[nx][ny] == 1:
                        grid[nx][ny] = 2
                        count -= 1
                        quene.append((nx, ny))
    if count > 0:
        return -1
    return res

堆/优先队列

1、LC215【数组中第k大元素】

快排

# 数组中第k大元素
# 快排
def solve(nums, k):
    k = len(nums) - k
    start = 0
    end = len(nums) - 1
    while True:
        loc = kernel(nums, start, end)
        if loc == k:
            return nums[loc]
        elif loc < k:
            start = loc + 1
        else:
            end = loc - 1
def kernel(nums, start, end):
    low = start
    high = end
    base = nums[start]
    while low < high:
        while low < high and nums[high] >= base:
            high -= 1
        nums[low] = nums[high]
        while low < high and nums[low] < base:
            low += 1
        nums[high] = nums[low]
    nums[low] = base
    return low

堆排

# 堆排
def solve(nums, k):
    n = len(nums)
    build_max_heap(nums, n)
    for k in range(n-1, n-k-1, -1):
        nums[0], nums[k] = nums[k], nums[0]
        heapify(nums, k, 0)
    return nums[k]
def build_max_heap(nums, n):
    i = n // 2
    while i >= 0:
        heapify(nums, n, i)
        i -= 1
def heapify(nums, n, i):
    l = 2 * i 
    r = 2 * i + 1
    largest = i
    if l < n and nums[l] > nums[i]:
        largest = l
    if r < n and nums[r] > nums[largest]:
        largest = r
    if largest != i:
        nums[largest], nums[i] = nums[i], nums[largest]
        heapify(nums, n, largest)
        

二分查找

链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

1、LC374【猜数字大小】

# 猜数字大小
def solve(n):
    left, right = 1, n
    while left < right:
        mid = left + (right - left) // 2
        if guess(mid) <= 0:
            right = mid
        else:
            left = mid + 1
    return left

2、LC2300【咒语和药水的成功对数】

# 咒语和药水的成功对数
def solve(spells, potions, success):
    res = [0] * len(spells)
    idx = [i for i in range(len(spells))]
    idx.sort(key=lambda x:spells[x])
    potions.sort(key=lambda x:-x)
    j = 0
    for p in idx:
        v = spells[p]
        while j < len(potions) and potions[j] * v >= success:
            j += 1
        res[p] = j
    return res

3、LC162【寻找峰值】

# 寻找峰值
def solve(nums):
    n = len(nums)
    left, right = 0, n-1
    while left < right:
        mid = left + (right - left) // 2
        if nums[mid] > nums[mid+1]:
            right = mid
        else:
            left = mid + 1
    return right

4、LC875【爱吃香蕉的珂珂】

# 爱吃香蕉的珂珂
import math
def solve(piles, h):
    l, r = 1, max(piles)
    while l < r:
        mid = l + (r - l) // 2
#         mid  = (l + r) // 2
        print(mid)
        if check(mid, piles, h):
            r = mid
        else:
            l = mid + 1
    return r
def check(mid, piles, h):
    cost = 0
    for each in piles:
        cur = math.ceil(each / mid)
        cost += cur
    return cost <= h
    

回溯

1、LC17【电话号码的字母组合】

# 字母组合
def solve(digits):
    if not digits:
        return []
    mapping = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
    res = []
    path = []
    n = len(digits)
    if n == 0:
        return n
    def back(i):
        if i == n:
            res.append(''.join(path))
            return
        for each in mapping[int(digits[i])]:
            path.append(each)
            back(i+1)
            path.pop()
    back(0)
    return res
            

2、LC46【全排列】

# 全排列
def solve(nums):
    n = len(nums)
    res = []
    def back(i):
        if i == n - 1:
            res.append(nums[:])
            return
        for j in range(i, n):
            nums[i], nums[j] = nums[j], nums[i]
            back(i + 1)
            nums[i], nums[j] = nums[j], nums[i]
    back(0)
    return res

3、LC39【组合总和】【同一个数字可以多次使用】

# 组合总和
def solve(candidates, target):
    res = []
    path = []
    candidates.sort()
    start = 0
    n = len(candidates)
    def back(path, target, candidates, start, res):
        if target == 0:
            res.append(path[:])
            return
        for i in range(start, n):
            if target - candidates[i] < 0:
                break
            path.append(candidates[i])
            back(path, target-candidates[i], candidates, i, res)
            path.pop()
    back(path, target, candidates, start, res)
    return res
    

4、LC40【组合总和2】【同一个数字只能用一次】

# 组合总和2
def solve(candidates, target):
    res = []
    path = []
    candidates.sort()
    start = 0
    n = len(candidates)
    def back(path, target, candidates, start, res):
        if target == 0:
            res.append(path[:])
            return
        for i in range(start, n):
            if target - candidates[i] < 0:
                break
            # 与组合1不同之处
            if i > start and candidates[i] == candidates[i-1]:
                continue
            path.append(candidates[i])
            # 与组合1不同之处
            back(path, target-candidates[i], candidates, i+1, res)
            path.pop()
    back(path, target, candidates, start, res)
    return res
    

动态规划一维

1、LC1137【泰波那契数】

# 泰波那契数
def solve(n):
    if n < 2:
        return n
    f = [0, 0, 1]
#     if n < 3:
#         return f[n]
    s = 1
    f0, f1, f2 = f[0], f[1], f[2]
    for i in range(3, n+1):
        f0 = f1
        f1 = f2
        f2 = s
        s = f0 + f1 + f2
    return s

2、LC746【最小花费爬楼梯】

# 最小花费爬楼梯
def solve(cost):
    n = len(cost)
    dp = [0] * (n+1)
    for i in range(2, n+1):
        dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
    return dp[n]

3、LC198【打家劫舍】

# 打家劫舍
def solve(nums):
    n = len(nums)
    dp = [0] * n
    if n == 1:
        return nums[0]
    dp[0] = nums[0]
    dp[1] = max(nums[0], nums[1])
    for i in range(2, n):
        dp[i] = max(dp[i-1], dp[i-2]+nums[i])
    return dp[n-1]

4、LC322【零钱兑换】 

# 零钱兑换
def solve(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0
    for coin in coins:
        for i in range(coin, amount + 1):
            dp[i] = min(dp[i], dp[i - coin] + 1)
    if dp[amount] != float('inf'):
        return dp[amount]
    else:
        return -1

5、LC518【零钱兑换2】

# 零钱兑换
def solve(amount, coins):
    dp = [0] * (amount + 1)
    dp[0] = 1
    for coin in coins:
        for i in range(coin,amount+1):
            dp[i] += dp[i-coin]
    return dp[amount]

 

动态规划二维

1、LC62【不同路径】

# 不同路径
def solve(m, n):
    dp = [[0] * n for i in range(m)]
    for i in range(n):
        dp[0][i] = 1
    for j in range(m):
        dp[j][0] = 1
    for i in range(1,m):
        for j in range(1,n):
            dp[i][j] = dp[i-1][j] + dp[i][j-1]
    return dp[m-1][n-1]

2、LC1143【最长公共子序列】

# 最长公共子序列
def solve(text1, text2):
    m, n = len(text1), len(text2)
    dp = [[0] * (n+1) for i in range(m+1)]
    res = 0
    for i in range(1, m+1):
        for j in range(1, n+1):
            if text1[i-1] == text2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
            res = max(res, dp[i][j])
    return res

3、LC714【买卖股票的最佳时机】【含手续费】

# 买卖股票的最佳时机【含手续费】
def solve(prices, fee):
    n = len(prices)
    dp = [[0] * 2 for i in range(n)]
    dp[0][1] = -prices[0]
    for i in range(1, n):
        dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
        dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
    return dp[n-1][0]

4、LC72【编辑距离】

# 编辑距离
def solve(word1, word2):
    m, n = len(word1), len(word2)
    dp = [[0] * (n+1) for i in range(m+1)]
    for i in range(1, m+1):
        dp[i][0] = dp[i-1][0] + 1
    for j in range(1, n+1):
        dp[0][j] = dp[0][j-1] + 1
    for i in range(1, m+1):
        for j in range(1, n+1):
            if word1[i-1] == word2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j]+1, dp[i][j-1]+1)
    return dp[m][n]

位运算

1、LC338【比特位计数】

# 比特位计数
def solve(n):
    res = []
    def count(x):
        cnt = 0
        while x > 0:
            x = x & (x - 1)
            cnt += 1
        return cnt
    for i in range(n+1):
        res.append(count(i))
    return res

2、LC136【只出现一次的数字】

# 只出现一次的数字
def solve(nums):
    x = 0
    for each in nums:
        x = x ^ each
    return x

区间集合

1、LC435【无重叠区间】

# 无重叠区间
def solve(intervals):
    n = len(intervals)
    intervals.sort(key=lambda x:x[1])
    right = intervals[0][1]
    ans = 1
    for i in range(1, n):
        if intervals[i][0] >= right:
            ans += 1
            right = intervals[i][1]
    return n - ans

2、LC452【用最少数量的箭引爆气球】

# 用最少数量的箭引爆气球
def solve(points):
    n = len(points)
    points.sort(key=lambda x:x[1])
    right = points[0][1]
    ans = 1
    for i in range(1, n):
        if points[i][0] > right:
            ans += 1
            right = points[i][1]
    return ans
                

单调栈

1、LC739【每日温度】

# 每日温度
def solve(temperatures):
    n = len(temperatures)
    stack = []
    ans = [0] * n
    for i in range(n):
        cur = temperatures[i]
        while stack and cur > temperatures[stack[-1]]:
            pre_index = stack.pop()
            ans[pre_index] = i - pre_index
        stack.append(i)
    return ans

2、LC901【股票价格的跨度】

class StockSpanner:

    def __init__(self):
        self.stack = [(-1, inf)]
        self.idx = -1
    def next(self, price: int) -> int:
        self.idx += 1
        while price >= self.stack[-1][1]:
            self.stack.pop()
        self.stack.append((self.idx, price))
        return self.idx - self.stack[-2][0]


# Your StockSpanner object will be instantiated and called as such:
# obj = StockSpanner()
# param_1 = obj.next(price)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值