ACM算法

1、数据结构的存储方式

数组由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间。但正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,时间复杂度 O(N);而且你如果想在数组中间进行插入和删除,每次必须搬移后面的所有数据以保持连续,时间复杂度 O(N)。

链表因为元素不连续,而是靠指针指向下一个元素的位置,所以不存在数组的扩容问题;如果知道某一元素的前驱和后驱,操作指针即可删除该元素或者插入新元素,时间复杂度 O(1)。但是正因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问;而且由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。

2、数据结构基本操作——遍历+访问

线性

​ for/while

void traverse(int[] arr) {			
    for (int i = 0; i < arr.length; i++) { 
        // 迭代访问 arr[i] 
    } 
} 

非线性

​ 递归

链表遍历框架–兼具迭代和递归结构

class ListNode{
		int val;
		ListNode next;	
}

void traverse(ListNode head){
		for(ListNode p=head; p!=null; p=p.next;){
			//迭代访问 p.val
		}
}

void traverse(ListNode head){
		//递归访问
		traverse(head.next);
}

二叉树遍历框架–典型非线性递归遍历结构

class TreeNode{
    int val;
    TreeNode left, right;
}

void traverse(TreeNode root){
    // 前序遍历
    traverse(root.left);
    //中序遍历
    traverse(root.right);
    //后序遍历
}

N 叉树遍历框架

class TreeNode{
    int val;
    TreeNode[] children;
}

void traverse(TreeNode root){
    for(TreeNode child : root.children){
				traverse(child)
    }	
}

labuladong公众号目录

labuladong算法秘籍目录

labuladong刷题笔记目录

3、算法

3.1、二叉树

3.1、DFS(深度优先),BFS(广度优先)

遍历

3.2、动态规划

动规问题一般形式就是求最值
​比如求最长递增子序列,最小编辑距离
​求解动态规划核心问题是穷举
​动规穷举特点——存在重叠子问题
​暴力穷举效率低下,需要备忘录或 DP table 优化穷举过程
​动规问题一定具备最优子结构,才能通过子问题的最值得到原问题最值
​列出正确的状态转移方程才能正确地穷举

# 自顶向下递归的动态规划
def dp(状态1, 状态2, ...):
    for 选择 in 所有可能的选择:
        # 此时的状态已经因为做了选择而改变
        result = 求最值(result, dp(状态1, 状态2, ...))
    return result
 
# 自底向上迭代的动态规划
# 初始化 base case
dp[0][0][...] = base case
# 进行状态转移
for 状态1 in 状态1的所有取值:
    for 状态2 in 状态2的所有取值:
        for ...
            dp[状态1][状态2][...] = 求最值(选择1,选择2...)

1、labuladong题目

凑零钱-普通递归-备忘录优化-dp数组优化

0-1背包问题

2、牛客网题目

HJ16购物单Code

3、力扣题目 动态规划-题目列表

123. 买卖股票的最佳时机 IIICode

188. 买卖股票的最佳时机 IVCode

309. 最佳买卖股票时机含冷冻期Code

714. 买卖股票的最佳时机含手续费Code

198. 打家劫舍CodeCode2

213. 打家劫舍 IICodeCode2

面试题 17.16. 按摩师Code

55. 跳跃游戏Code

3.2、回溯算法

主要是一个决策树的遍历过程

路径:已做出的选择
选择列表:当前可以做的选择
结束条件:到达决策树底层,无法再做选择

result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    
    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择

3.3、双指针

快慢指针解决链表中的问题,比如典型的判定链表中是否包含环;
左右指针解决数组(或者字符串)中的问题,比如二分查找。

3.3、滑动窗口

解决子串、子数组问题

4、其他

4.1、排列组合

排列与组合的定义和公式-高中知识点
Java8排列(6行代码实现)
组合算法Java实现-可以修改下start起始为0并判断已有字符存在可修改为排列算法

4.2、排序算法

常见的八大排序算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值