当前位置: 首页 > news >正文

力扣小题, 力扣113.路径总和II力扣.111二叉树的最小深度 力扣.221最大正方形力扣5.最长回文子串更加优秀的算法:中心扩展算法

 

目录

 

力扣113.路径总和II

力扣.111二叉树的最小深度

 力扣.221最大正方形

力扣5.最长回文子串

更加优秀的算法:中心扩展算法


力扣113.路径总和II

这道题,让我明白回溯了到底啥意思

之前我找的时候,我一直在想,如果可以,请你对比一下这个代码和下面那个代码

我们这个相当于自动回溯,因为他是引用传递,所以说就不用维护了

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public  List<List<Integer>>ret=new LinkedList<>();public  List<Integer>res=new LinkedList();int targetSum=0;public  List<List<Integer>> pathSum(TreeNode root, int _targetSum) {targetSum=_targetSum;dfs(root,0);return ret;}public  void dfs(TreeNode root,int count){  if(root==null)return;count+=root.val;res.add(root.val);if(count==targetSum&&root.left==null&&root.right==null){ret.add(new LinkedList<>(res));}dfs(root.left,count);dfs(root.right,count);res.removeLast();}
}

这个是错误代码,为什么这个是错误的,上面确实正确的呢,是因为

下面这个我们无法回溯,你回溯要有一个计数器那种,怎么维护这个计数器是关键,我假如使用下面的这个,我们回溯,减法的话,怎么减去呢,我如果使用减法回溯计数器,我就要知道他回溯前的节点是什么,可是我们无法知道回溯前 的节点是啥,所以下面这个错误 

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public static List<List<Integer>>ret=new LinkedList<>();public static List<Integer>res=new LinkedList();static int count=0;static int targetSum=0;public static List<List<Integer>> pathSum(TreeNode root, int _targetSum) {targetSum=_targetSum;dfs(root);return ret;}public static void dfs(TreeNode root){  if(root==null)return;count+=root.val;res.add(root.val);if(count==targetSum&&root.left==null&&root.right==null){ret.add((List<Integer>) res);}dfs(root.left);dfs(root.right);res.removeLast();}
}

力扣.111二叉树的最小深度

这个正常情况好想,你假如剪枝的话,就不是很好想了,看代码分析,

他的剪枝分在两个地方,第一个到了叶子结点,不再往后遍历,第二个是当前最大深度已经比最小的深度大了,就直接放弃就好了

class Solution {int ans = Integer.MAX_VALUE;public int minDepth(TreeNode root) {if(root == null) {return 0;}dfs(root, 0);return ans;}private void dfs(TreeNode root, int cnt) {if(root == null) {return;}//记录每一层cnt++;if(cnt > ans) {//比最小值大,直接排除return;}//这一步可能就是假如左右端点都为空,那么我就不去遍历了。减去叶子结点的下面(因为我已经到达最下面的节点了。)if(root.left == root.right) {ans = Math.min(ans, cnt);return;}dfs(root.left, cnt);dfs(root.right, cnt);}
}

 力扣.221最大正方形

太久没写动规了,回顾一下

我们只需要会一个,也是最难的状态定义

这里定义i,j位置为以i,j为右下角的最大正方形边长

那么初始化这件事不知道你能不能想出来,右下角的话你的最左边一行,和最上边一行是不是都要初始化为1,假如哪个原先位置字符是1的话,你想一下,右下角,你怎么可以拿最左边和最上边为右下角呢

然后他的边长,我是这么想的,你看这个图,假如想要边长变大,是不是,你的左边,上面,以及你的对角线那个位置都要是1,不然你不可能是正方形(或者说,正方形的边长,那么dp[][]这些位置,肯定都要有值

class Solution {public int maximalSquare(char[][] matrix) {int n=matrix.length;int m=matrix[0].length;//dp[i][j] 在i,j位置,包含1的最大正方形,int[][]dp=new int[n][m];for(int i=0;i<n;i++){    if(matrix[i][0]=='1'){dp[i][0]=1;}}for(int j=0;j<m;j++){if(matrix[0][j]=='1'){dp[0][j]=1;}}int maxSide=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(matrix[i][j]=='1'&&(i!=0&&j!=0)){dp[i][j]=Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i][j-1]))+1;   }maxSide=Math.max(maxSide,dp[i][j]);}}return maxSide*maxSide;}
}

力扣5.最长回文子串

这个题,你首先明确状态转移方程

boolean[][]dp 他是i位置开头,j位置结尾,那我问你,我两边相等,我是不是要检查中间,然后后面就这么些,前面的判断是因为,一个字符,或者两个字符,我可以直接给他判定为回文

  public static String longestPalindrome(String s) {int n=s.length();//dp[i][j]:设置以i位置开头,j位置结尾的dpint len=1;int begin=0;//判断i位置开头,j位置结尾的dp。boolean[][]dp=new boolean[n][n];//检查,从后往前找,因为 [i,j] =[i+1][j-1]for(int i=n-1;i>=0;i--){for(int j=i;j<n;j++){if(s.charAt(i)==s.charAt(j)){if(i==j||i+1==j){//a ,aa 两个字符或者一个字符的情况  babaddp[i][j]=true;}else{//中间有字符,接下来看看i+1和j-1这个位置看看,为啥要到这个位置看,我今天才搞明白,// 是因为我需要看你里面是不是回文字符串,假如他俩下标不挨着,那么就看看中间有没有不是回文的//换句话说,计算机思路先检查外面,再检查里面。dp[i][j]=dp[i+1][j-1];}}//假如发现当前i,j位置是true,就说明是回文if(dp[i][j]==true&&j-i+1>len){//随时更新开始值和最长长度len=j-i+1;begin=i;}}}return s.substring(begin,begin+len);}

更加优秀的算法:中心扩展算法

以每个点作为中心去计算他的回文数。

class Solution {public String longestPalindrome(String s) {//中心拓展算法int n=s.length();char[]a=s.toCharArray();String c="";int max=0;for(int i=0;i<n;i++){int left=i-1;int right=i+1;while(left>=0&&right<n){if(a[left]==a[right]){left--;right++; }else{break;}}if(right-left-1>max){c=s.substring(left+1,right);max=right-left-1;}left=i;right=i+1;while(left>=0&&right<n){if(a[left]==a[right]){left--;right++; }else{break;}}if(right-left-1>max){c=s.substring(left+1,right);max=right-left-1;}}return c;}
}

差距不大,算法一致,快了10ms差不多

class Solution {public String longestPalindrome(String s) {//中心拓展算法int n=s.length();char[]a=s.toCharArray();String c="";int max=0;for(int i=0;i<n;i++){int left=i-1;int right=i+1;//我直接 aba 这种while(left>=0&&right<n){//两个相等就不变指针if(a[left]==a[right]){left--;right++; }else{//不等就退出循环break;}}//因为出来的话俩个都是不等,所以   kabac   left=k    right=c 你减一下if(right-left-1>max){c=s.substring(left+1,right);max=right-left-1;}//aa这种left=i;right=i+1;while(left>=0&&right<n){if(a[left]==a[right]){left--;right++; }else{break;}}if(right-left-1>max){c=s.substring(left+1,right);max=right-left-1;}}return c;}
}

相关文章:

  • 获取印度股票市场API
  • Java使用CollectionUtils集合工具类
  • Unity Shader入门(更新中)
  • Lucide:一款精美的开源矢量图标库,前端图标新选择
  • RS485转PROFINET:让废水处理从“人工监控”到“智能管控”​​
  • PyQt学习系列02-模型-视图架构与数据管理
  • DOM API-JS通过文档对象树操作Doc和CSS
  • 其他有关Oracle BUFFER CACHE的优化思路
  • Go语言之Map 的基本操作-《Go语言实战指南》
  • LeetCode 257. 二叉树所有路径求解:回溯算法的深度解析与实践
  • MySQL中InnoDB引擎逻辑存储结构、B+树索引结构、B+树高度及存储数据量
  • 前端父元素flex布局设置左右padding时,input溢出父元素右内边距无效
  • 我的世界模组开发——物理学(1)
  • VPLC (VPLCnext) K8S
  • YOLO学习笔记 | YOLO11对象检测,实例分割,姿态评估的TensorRT部署c++
  • 企业网站架构部署与优化第4章Nginx核心功能
  • C++ HTTP框架推荐
  • AI|Java开发 IntelliJ IDEA中接入本地部署的deepseek方法
  • docker-安装部署于macOS11
  • 防震基座在半导体晶圆制造设备抛光机详细应用案例-江苏泊苏系统集成有限公司
  • 菲律宾做网站/搜狗站长推送工具
  • 广告设计图片简单/天津搜索引擎seo
  • 网站管理 上传模板/武汉seo排名扣费
  • ps建设网站步骤/永州网络推广
  • 网站建设需要知道什么/百度网盘app免费下载安装老版本
  • 合肥有多少建网站公司/谷歌浏览器手机版