刷题总结

 

数组、链表、跳表:

一般暴力可解决,优化思想一般有双指针、升维

1、数组

283 移动零

11 盛最多水的容器

70 爬楼梯

15 三数之和

2、链表

206 反转链表

24 两两交换链表中的节点

141 环形链表

142 环形链表II

25 K个一组翻转链表

3、其他

26 删除排序数组中的重复项

27 旋转数组

28 合并两个有序链表

30 两数之和

31 加一

 

栈:

具有最近相关性的问题,使用栈

队列:

具有先来后到特点的问题,使用队列

滑动窗口都使用队列

20 有效的括号

155 最小栈

84 柱状图中最大的矩形

239 滑动窗口最大值

641 设计循环双端队列

42 接雨水

 

哈希表、映射、集合

242 有效的字母异位词

49 字母异位词分组

1 两数之和

 

树、二叉树、二叉搜索树

树问题的解法都是递归

树的题目解法比较固定,要么深搜要么广搜

94 二叉树的中序遍历

144 二叉树的前序遍历

590 N叉树的后序遍历

589 N叉树的前序遍历

429 N叉树的层序遍历

 

递归

递归的基本思想为:1、找最近重复子问题;2、数学归纳法

递归的步骤为:1、递归终止条件;2、处理当层逻辑;3、跳到下一层;4、清理当前层

递归的代码模板:

public void recur(int level, int param) {
    //1、递归出口
    if (level > MAX_LEVEL) {
        //处理结果
        return;
    }

    //2、处理当前逻辑(参数发生变化)
    param = process(level, param);

    //3、进入下一层(缩小问题规模:子问题)
    recur(level+1, param);

    //4、逆处理(将参数回退到之前的状态)
    param = inverseProcess(level, param);
}

相关题目:

70 爬楼梯

22 括号生成

226 翻转二叉树

98 验证二叉搜索树

104 二叉树的最大深度

其他:

111 二叉树的最小深度

297 二叉树的序列化与反序列化

236 二叉树的最近公共祖先

105 从前序与中序遍历序列构造二叉树

77 组合

46 全排列

47 全排列II

 

分治、回溯

将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同

求出子问题的解,即可得到原问题的解。

简单问题可用二分法解决

50 Pow(x, n)

78 子集

169 多数元素

17 电话号码的字母组合

51 N皇后

 

深搜、广搜

1、深搜

1)递归写法

def dfs(node, visited):
    #终止
    if node in visited:
        return

    visited.add(node)
    ...
    for next_node in node.children():
        if not next_node in visited:
            dfs(next_node, visited)

2)可以用栈

2、广搜

BFS代码结构

def BFS(graph, start, end):
    queue = []
    queue.append([start])
    visited.add(start)

    while queue:
        node = queue.pop()
        visited.add(node)

        process(node)
        nodes = generate_related_nodes(node)
        queue.push(nodes)

102 二叉树的层序遍历

433 最小基因变化

22 括号生成

515 在每个树行中找最大值

其他:

127 单词接龙

126 单词接龙II

200 岛屿数量

529 扫雷游戏

 

贪心算法

贪心算法是一种在每一步选择中都采取在当前状态下最好或最优的选择,不能回退

动态规划会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能

322 零钱兑换

860 柠檬水找零

122 买卖股票的最佳时机

455 分发饼干

874 模拟行走机器人

55 跳跃游戏

45 跳跃游戏II

 

二分查找

1、二分查找的前提

1)目标函数单调性

2)存在上下界

3)能够通过索引访问

2、代码模板

left, right = 0, len(array)-1
while left <= right:
    mid = (left + right) / 2
    if array[mid] == target:
        # find the target
        break or return result
    elif array[mid] < target:
        left = mid + 1
    else:
        right = mid - 1

3、相关题目

69 x的平方根

367 有效的完全平方数

33 搜索旋转排序数组

74 搜索二维矩阵

153 妱旋转排序数组中的最小值

 

动态规划

1、关键点

动态规划和递归或者分治没有根本上的区别(关键看有无最优子结构)

共性:找到重复子问题

差异性:最优子结构、中途可以淘汰次优解

2、解题思路

1)最优子结构 opt[n] = best_of(opt[n-1], opt[n-2], ...);

2)存储中间状态opt[i]

3)递推公式(状态转移方程或DP方程)

Fib:opt[n-1] + opt[n-2]

4)二维路径:opt[i, j] = opt[i+1, j] + opt[i][j+1](判断opt[i, j]是否空地)

3、相关题目

62 不同路径

63 不同路径II

1143 最长公共子序列

70 爬楼梯

120 三角形最小路径和

53 最大子序和

152 乘积最大子数组

63 不同路径II

322 零钱兑换

 

 

排序算法

 

其余不常见的

字典树、并查集、高级搜索、红黑树、AVL树、位运算、布隆过滤器、LRU缓存

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值