70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2

输出: 2

解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶

    示例 2:

输入: 3

输出: 3

解释: 有三种方法可以爬到楼顶。

  1. 1 阶 + 1 阶 + 1 阶
  2. 1 阶 + 2 阶
  3. 2 阶 + 1 阶

思路

//动态规划 二维矩阵
//递归,即斐波那契数列 可以有以下四个解法
//找最近重复性???

solution1 傻递归

//45阶时超时
class Solution {
public int climbStairs(int n) {
if (n<=2) return n;
else return climbStairs(n-1) + climbStairs(n-2);
}
}

solution2 迭代

class Solution {
public int climbStairs(int n) {
if (n<=2) return n;
int a = 1,b=2;
while(n-->2){ //运行与后面的数的差次数
int sum= a + b;
a = b;
b = sum;
}
return b;
}
}

solution3 高级递归

//自顶向下 对计算过的进行保存
class Solution {
int[] cache = new int[100];
public int climbStairs(int n) {
if (n<=2) return n;
else if (cache[n] != 0) return cache[n];
else return cache[n] = climbStairs(n-1) + climbStairs(n-2);
}
}

solution3 动态规划

//从下到上至要抵达的台阶
class Solution {
public int climbStairs(int n) {
int[] cache = new int[n+1];
cache[1] = 1;
cache[0] = 1;
for (int i = 2;i<=n;i++){
cache[i] = cache[i-1]+cache[i-2];
}
return cache[n];
}
}

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例:

输入:n = 3

输出:[

"((()))",

"(()())",

"(())()",

"()(())",

"()()()"

]

思路

//递归 不断生成左右括号
//递归1 生成全部情况,过滤掉不合法的情况
//递归2 一边生成符号,一边保留格式正常的
//找最小重复性

solution 1

class Solution {
private List<String> result;
public List<String> generateParenthesis(int n) {
result = new ArrayList<>();
_generate(0, 2*n, "");
return result;
}
private void _generate(int curr,int n,String s){
//停止递归
if (curr == n) {
_filter(s);
return; }
//当前层
//下一层
_generate(curr+1,n,s+'(');
_generate(curr+1,n,s+')');
}
private void _filter(String s){
Stack<Character> st = new Stack<>();
for (char c : s.toCharArray()){
if(c == '(') st.push(c);
else {
if (!st.isEmpty()){
st.pop();
}else {
return;
}
}
}
if (st.isEmpty()) result.add(s);
}
}

solution 2

class Solution {
private List<String> result;
public List<String> generateParenthesis(int n) {
result = new ArrayList<>();
_generate(0,0,n,"");
return result;
}
private void _generate(int left,int right,int n,String s){
//抵达最后一层,停止递归
if (left == n && right == n) {
result.add(s);
return;
}
//当前层
//下一层
// 左括号数量大于右括号数量时,添加右括号
if (left < n) {
_generate(left+1,right,n,s+'(');
}
if (left > right) {
_generate(left,right+1,n,s + ")");
} }
}
class Solution {
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>();
_generate(result,0,0, 2*n, "");
return result;
}
private void _generate(List<String> result,int left,int right,int max,String s){
if (s.length() == max) {
result.add(s);
return; }
if (left < max/2) _generate(result,left+1,right,max,s+'(');
if (right < left) _generate(result,left,right+1,max,s+')');
}
}

98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。

节点的右子树只包含大于当前节点的数。

所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:

2

/

1 3

输出: true

示例 2:

输入:

5

/

1 4

/

3 6

输出: false

解释: 输入为: [5,1,4,null,null,3,6]。

根节点的值为 5 ,但是其右子节点值为 4 。

错误思路

//没有考虑是整个子树的比较而不只是结点的比较
class Solution {
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
//终止条件
if (root.left == null && root.right == null) return true;
//当前层
if (root.left != null && root.left.val >= root.val) return false;
if (root.right != null && root.right.val <= root.val) return false;
return isValidBST(root.left) && isValidBST(root.right);
}
}

思路整理

//思路1:传入根结点进入递归(错) 传入结点对应树的最小和最大值(对)
//思路2:中序遍历为升序即true

solution1递归

class Solution {
public boolean isValidBST(TreeNode root) {
return helper(root,null,null);
}
public boolean helper(TreeNode root,Integer low,Integer up){
//终止层
if (root == null) return true;
//当前层
if (low!=null && root.val <= low) return false;
if (up!=null && root.val >= up) return false;
//下一层
return helper(root.left,low,root.val) && helper(root.right,root.val,up);
}
}

solution2 中序遍历

class Solution {
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
double inorder = -Double.MAX_VALUE;
while(!st.isEmpty() || root != null){
while(root!=null){
st.push(root);
root = root.left;
}
root = st.pop();
if (root.val <= inorder) return false;
inorder = root.val;//取左子树为最小值
root = root.right;//遍历右子树
}
return true;
}
}
// 甜姨解法
class Solution {
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
//访问左子树(递归到底)
if (!isValidBST(root.left)) return false;
//访问当前结点
if (root.val<=pre) return false;
pre = root.val;
//访问右子树
return isValidBST(root.right); }
}

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

3

/

9 20

/

15 7

返回它的最大深度 3 。

思路

//递归1、(如果有子树就加1并递归下一层)
//迭代1 深度优先
//迭代2 广度优先

solution1 递归

class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return helper(root,1);
}
public int helper(TreeNode root,int max) {
if (root.left == null && root.right == null) return max;
//当前层 和下一层
int left = 0;
int right = 0;
if (root.left != null) left = helper(root.left, max+1);
if (root.right != null) right = helper(root.right,max+1);
return Math.max(right,left); }
}
//简洁版
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
else {
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left,right)+1;
}
}
}
// 无敌版
class Solution {
public int maxDepth(TreeNode root) {
return root == null?0:Math.max(maxDepth(root.right),maxDepth(root.left))+1;
}
}

solution2 迭代

class Solution {
public int maxDepth(TreeNode root) {
TreeNode node = root;
Stack<TreeNode> nodest = new Stack<>();
Stack<Integer> depthst = new Stack<>();
int max = 0;
int depth = 1;
while (node !=null || nodest.size() > 0){
if (node!=null) {
nodest.push(node);
depthst.push(depth);
node = node.left;
depth++;
}else{
//当前结点为空,即该左树结束
node = nodest.pop();
depth = depthst.pop();
if(depth>max) max = depth;
// 遍历右子树
node = node.right;
depth++;
}
}
return max;
}
}

LeetCode 递归篇(70、22、98、104)的更多相关文章

  1. LeetCode刷题总结-递归篇

    递归是算法学习中很基本也很常用的一种方法,但是对于初学者来说比较难以理解(PS:难点在于不断调用自身,产生多个返回值,理不清其返回值的具体顺序,以及最终的返回值到底是哪一个?).因此,本文将选择Lee ...

  2. Recursive - leetcode [递归]

    经验tips: Recursion is the best friend of tree-related problems. 一是只要遇到字符串的子序列或配准问题首先考虑动态规划DP,二是只要遇到需要 ...

  3. [LeetCode]题解(python):104 Maximum Depth of Binary Tree

    题目来源 https://leetcode.com/problems/maximum-depth-of-binary-tree/ Given a binary tree, find its maxim ...

  4. LeetCode 递归(Recursion) 培训专题 讲解文章翻译 (附链接)

     递归 - 时间复杂度 在本文中, 我们主要介绍如何分析递归算法程序中的时间复杂度.. 在一个递归程序中, 它的时间复杂度 O(T) 一般来说就是他总共递归调用的次数 (定义为 R) 以及每次调用时所 ...

  5. LeetCode Weekly Contest 70 A B C D

    A. K-th Symbol in Grammar Description On the first row, we write a 0. Now in every subsequent row, w ...

  6. LeetCode || 递归 / 回溯

    呜呜呜 递归好不想写qwq 求“所有情况”这种就递归 17. Letter Combinations of a Phone Number 题意:在九宫格上按数字,输出所有可能的字母组合 Input: ...

  7. eetCode刷题-递归篇

    递归是算法学习中很基本也很常用的一种方法,但是对于初学者来说比较难以理解(PS:难点在于不断调用自身,产生多个返回值,理不清其返回值的具体顺序,以及最终的返回值到底是哪一个?).因此,本文将选择Lee ...

  8. leetcode刷题-95/96/98

    题目95题 给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 . 示例: 输入:3输出:[  [1,null,3,2],  [3,2,null,1],  [3,1,null,n ...

  9. LeetCode Javascript实现 258. Add Digits 104. Maximum Depth of Binary Tree 226. Invert Binary Tree

    258. Add Digits Digit root 数根问题 /** * @param {number} num * @return {number} */ var addDigits = func ...

  10. LeetCode递归解题模板

    39 40 78. Subsets https://leetcode.com/problems/subsets/description/ void subsets(vector<int>& ...

随机推荐

  1. 【图像处理】如何使用matplotlib 库显示灰度图像为自定义颜色

    项目场景 我这里有一张名为airplane.jpg的灰度图像灰度图像 使用 matplotlib 库读取并显示: import matplotlib.pyplot as plt root=" ...

  2. umich cv-3-2

    UMICH CV Neural Network 既然谈到神经网络,我们肯定要讨论在神经网络中是如何进行梯度的计算以及参数的优化的 传统的方法就是我们手动计算梯度,但是随着神经网络层数的增加,这种方法显 ...

  3. nodejs修改npm包安装位置

    适用于非个人电脑.便携使用 npm config set cache D:\nodejs\node_cache npm config set prefix D:\nodejs npm config s ...

  4. c#组合模式详解

    基础介绍:   组合模式用于表示部分-整体的层次结构.适用于希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象的情况.   顾名思义,什么叫部分-整体,比如常见的前端UI,一个 ...

  5. MySQL查看数据库性能常用命令和实战教学

    MySQL查看数据库性能常用命令 # 列出MySQL服务器运行各种状态值 show global status; # 查询MySQL服务器配置信息语句 show variables; # 慢查询 sh ...

  6. springboot整合jpa sqlite

    前言 最近有关项目需要用到SQLITE,我先是使用Mybatis去连接SQLITE,然后发现SQLITE对BLOB支持不好,在网上看到相关教程可以写mapper.xml文件,加一个handler解决B ...

  7. Windows系统下,GoLand的Terminal选定Git Bash作为终端,使用其上传代码时,出现中文乱码的问题

    问题描述 按照这位博主博客写的没有完全解决乱码问题博主博客 这个博主博客是我后来发现,暂时还没去验证是否可行博主博客 解决方案 notepad++直接Free Download,然后就一直下一步就无脑 ...

  8. Ansible操作MySQL常用的几个模块

    1. mysql_user 模块 mysql_user模块用来添加,删除用户以及设置用户权限 创建MySQL数据库的用户与口令(非root@localhost用户),直接通过playbooks中的案例 ...

  9. 手撕Vuex-模块化共享数据下

    前言 好,经过上一篇的介绍,了解了 Vuex 当中的模块化,本章主要介绍 Vuex 当中的模块化共享数据下篇. 我们知道在全局的 Store 对象当中,我们可以定义全局的数据,那么如果我们在模块当中也 ...

  10. 第一次使用 GoLand 启动 运行 Go 项目

    一.开始之前确保已经安装 go语言环境 二.新建项目 三.选择项目路径 四.在该目录下手动创建 bin,src两个文件夹 bin 用来存放编译后的 .exe 文件 src 我们的工程的开发文件存放的点 ...