算法题常见框架
算法题常见框架
一、树的遍历
刷题要先刷二叉树,因为二叉树最容易培养框架思维。
1、二叉树的遍历
分为前中后序遍历。
DLR--前序遍历(根在前,从左往右,一棵树的根永远在左子树前面,左子树又永远在右子树前面)
LDR--中序遍历(根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面)
LRD--后序遍历(根在后,从左往右,一棵树的左子树永远在右子树前面,右子树永远在根前面)
2、如何给二叉树的所有接点+1
3、力扣100题
验证两棵树是否相等
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q ==null){
return true;
}else if(p == null || q==null){
return false;
}else if(p.val != q.val){
return false;
}else{
boolean l = isSameTree(p.left,q.left);
boolean r = isSameTree(p.right, q.right);
return l && r;
}
}
}
4、力扣98题
验证二叉搜索树
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean isValidBST(TreeNode node, long lower, long upper) {
if (node == null) {
return true;
}
if (node.val <= lower || node.val >= upper) {
return false;
}
return isValidBST(node.left, lower, node.val) && isValidBST(node.right, node.val, upper);
}
}
5、序列化和反序列化二叉树
https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/qian-xu-bian-li-ji-jian-xie-fa-by-wu-wen-gvdp/
二、动态规划
应用场景:求最值
核心:穷举
三要素:重叠子问题、最优子结构、状态转移方程
1、斐波那契数列
Public int fid(int n){
If(n==0)return 0;
If(n==1||n==2)return 1;
return fid(n-1)+fid(n-2);
}
2、递归算法的时间复杂度:子问题个数乘以解决一个子问题所需要的时间。O(2的n次方),复杂度高,如何优化?重叠子问题,采用备忘录和DP数组,避免重复计算。使时间复杂度变为O(N),这样解决了重叠子问题。
斐波那契的几种递归方法。
① 暴力递归
public int fib(int n){
if(n==0) return 0;
return fib(n-1)+fib(n-2);
}
② 带备忘录的
// 带备忘录的
public int fib2(int n){
if (n==0) {return 0;}
int []tmp = new int[n+1];
return fib2Helper(tmp,n);
}
//自顶向下的
private int fib2Helper(int [] tmp, int n){
if (n ==1 ||n==2) return 1;
if (tmp[n]!=0) return tmp[n];
tmp[n] = fib2Helper(tmp, n-1)+ fib2Helper(tmp, n-2);
return tmp[n];
}
//自底向上的
public int fib3(int n ){
if (n==0) {return 0;}
if (n==1||n==2) return 1;
int []tmp = new int[n+1];
tmp[1] = tmp[2] = 1;
for (int i =3;i<=n;i++){
tmp[i] = tmp[i-1]+tmp[i-2];
}
return tmp[n];
}
3、需要刷的题。凑零钱 01背包和完全背包问题;
IDEA安装力扣插件
凑零钱
public int coinChange(int[] coins, int amount) {
if(coins.length == 0){
return -1;
}
int [] memo = new int[amount+1];
memo[0] = 0;
for(int i=1;i<=amount;i++){
int min = Integer.MAX_VALUE;
for(int j=0;j<coins.length;j++){
if(i-coins[j]>=0 && memo[i-coins[j]]<min){
min = memo[i-coins[j]] +1;
}
}
memo[i] = min;
}
return memo[amount] == Integer.MAX_VALUE?-1:memo[amount] ;
}