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

news2025/5/24 1:15:03

 

目录

 

力扣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位置结尾的dp
        int 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 两个字符或者一个字符的情况  babad
                        dp[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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-form elform 对齐方式调整

如下页面表单&#xff0c;展示后就很丑。 页面表单&#xff0c;有时候我们想着最左侧的应该合理整齐的左对齐&#xff0c;右侧的表单都是右对齐&#xff0c;这样页面看起来会整洁很多。 <el-form class"w-100 a_form" style"padding: 0 15px 0px 15px"…

JESD204 ip核使用与例程分析(二)

JESD204 ip核使用与例程分析(二) JESD204时钟方案专用差分时钟对例程分析jesd204_0_transport_layer_demapperjesd204_0_sig_chkjesd204_0_clockingjesd204_0 ip核port寄存器AXI-LITE寄存器配置jesd204_phy ip核JESD204时钟方案 图3-1所示为最通用、灵活的时钟解决方案。在图…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Blurry Loading (毛玻璃加载)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— Blurry Loading 组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ ✨ 组件目标 实现一个加载进度条&#xff0c;随着加载进度的…

演示:【WPF-WinCC3D】 3D工业组态监控平台源代码

一、目的&#xff1a;分享一个应用WPF 3D开发的3D工业组态监控平台源代码 二、功能介绍 WPF-WinCC3D是基于 WPF 3D研发的工业组态软件&#xff0c;提供将近200个预置工业模型&#xff08;机械手臂、科幻零部件、熔炼生产线、机加生产线、管道等&#xff09;&#xff0c;支持组态…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】1.4 数据库与表的基本操作(DDL/DML语句)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 1.4 数据库与表的基本操作&#xff08;DDL/DML语句&#xff09;1.4.1 数据库生命周期管理&#xff08;DDL核心&#xff09;1.4.1.1 创建数据库&#xff08;CREATE DATABASE&…

如何在电脑上登录多个抖音账号?多开不同IP技巧分解

随着短视频的爆发式增长&#xff0c;抖音已经成为许多人生活和工作的必备平台。不论是个人内容创作者、品牌商家&#xff0c;还是营销人员&#xff0c;都可能需要管理多个抖音账号。如何在电脑上同时登录多个抖音账号&#xff0c;提升工作效率&#xff0c;避免频繁切换账号的麻…

【东枫科技】usrp rfnoc 开发环境搭建

作者 太原市东枫电子科技有限公司 &#xff0c;代理销售 USRP&#xff0c;Nvidia&#xff0c;等产品与技术支持&#xff0c;培训服务。 环境 Ubuntu 20.04 依赖包 sudo apt-get updatesudo apt-get install autoconf automake build-essential ccache cmake cpufrequtils …

【JAVA资料,C#资料,人工智能资料,Python资料】全网最全编程学习文档合集,从入门到全栈,保姆级整理!

文章目录 前言一、编程学习前的准备​1.1 明确学习目标​1.2 评估自身基础​ 二、编程语言的选择​2.1 热门编程语言介绍​2.2 如何根据目标选择语言​ 三、编程基础学习​3.1 变量与数据类型​3.2 控制结构​3.3 函数​ 四、面向对象编程&#xff08;OOP&#xff09;​4.1 OOP…

[IMX] 05.串口 - UART

目录 1.通信格式 2.电平标准 3.IMX UART 模块 4.时钟寄存器 - CCM_CSCDR1 5.控制寄存器 5.1.UART_UCR1 5.2.UART_UCR2 5.3.UART_UCR3 6.状态寄存器 6.1.UART_USR1 6.2.UART_USR2 7.FIFO 控制寄存器 - UART_UFCR 8.波特率寄存器 8.1.分母 - UART_UBIR 8.2.分子 -…

使用Tkinter写一个发送kafka消息的工具

文章目录 背景工具界面展示功能代码讲解运行环境创建GUI程序搭建前端样式编写功能实现代码 背景 公司是做AR实景产品的&#xff0c;近几年无人机特别的火&#xff0c;一来公司比较关注低空经济这个新型领域&#xff0c;二来很多政企、事业单位都采购了无人机用于日常工作。那么…

MongoDB 与 EF Core 深度整合实战:打造结构清晰的 Web API 应用

题纲 MongoDB 字符串连接 URIC# 连接字符串实例 实现一个电影信息查询 demo创建项目创建实体实现 DbContext 上下文仓储实现服务实现控制器实现服务注册快照注入数据库连接配置1. 注册配置类2. 注入 IOptionsSnapshot<MongoDbSettings>3. 配置文件 appsettings.json 示例…

重写B站(网页、后端、小程序)

1. 网页端 1.1 框架 Vue ElementUI axios 1.2 框架搭建步骤 搭建Vue 1.3 配置文件 main.js import {createApp} from vue import ElementUi from element-plus import element-plus/dist/index.css; import axios from "axios"; import router from…

文档债务拖累交付速度?5大优化策略文档自动化

开发者在追求开发速度的过程中&#xff0c;往往会忽视文档的编写&#xff0c;如省略设计文档、代码注释或API文档等。这种做法往往导致在后期调试阶段需要花费三倍以上的时间来理解代码逻辑&#xff0c;进而形成所谓的文档债务&#xff0c;严重拖累交付速度并造成资源浪费。而积…

【数据结构与算法】LeetCode 每日三题

如果你已经对数据结构与算法略知一二&#xff0c;现在正在复习数据结构与算法的一些重点知识 ------------------------------------------------------------------------------------------------------------------------- 关注我&#x1f308;&#xff0c;每天更新总结文章…

基于深度学习的电力负荷预测研究

一、深度学习模型框架 在当今数字化时代&#xff0c;基于深度学习的电力负荷预测研究正成为保障电力系统稳定、高效运行的关键领域。其模型构建是一个复杂而精妙的过程&#xff0c;涉及多学科知识与前沿技术的融合应用。首先&#xff0c;要明确电力负荷预测的目标&#xff0c;…

篇章十 消息持久化(二)

目录 1.消息持久化-创建MessageFileManger类 1.1 创建一个类 1.2 创建关于路径的方法 1.3 定义内部类 1.4 实现消息统计文件读写 1.5 实现创建消息目录和文件 1.6 实现删除消息目录和文件 1.7 实现消息序列化 1. 消息序列化的一些概念&#xff1a; 2. 方案选择&#xf…

【IDEA】删除/替换文件中所有包含某个字符串的行

目录 前言 正则表达式 示例 使用方法 前言 在日常开发中&#xff0c;频繁地删除无用代码或清理空行是不可避免的操作。许多开发者希望找到一种高效的方式&#xff0c;避免手动选中代码再删除的繁琐过程。 使用正则表达式是处理字符串的一个非常有效的方法。 正则表达式 …

基于深度学习的不良驾驶行为为识别检测

一.研究目的 随着全球汽车保有量持续增长&#xff0c;交通安全问题日益严峻&#xff0c;由不良驾驶行为&#xff08;如疲劳驾驶、接打电话、急加速/急刹车等&#xff09;引发的交通事故频发&#xff0c;不仅威胁生命财产安全&#xff0c;还加剧交通拥堵与环境污染。传统识别方…

第十周作业

一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF&#xff1a;file_get_content实验&#xff0c;要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro

Python操作PDF书签详解 - 添加、修改、提取和删除

目录 简介 使用工具 Python 向 PDF 添加书签 添加书签 添加嵌套书签 Python 修改 PDF 书签 Python 展开或折叠 PDF 书签 Python 提取 PDF 书签 Python 删除 PDF 书签 简介 PDF 书签是 PDF 文件中的导航工具&#xff0c;通常包含一个标题和一个跳转位置&#xff08;如…