day24 131. 分割回文串40. 组合总和 II39. 组合总和

news/2025/2/15 21:50:58/文章来源:https://www.cnblogs.com/lin0304/p/18717448
    1. 分割回文串
      问题描述
      给定一个字符串 s,将字符串分割成若干个子字符串,使得每个子字符串都是回文串。返回所有可能的分割方式。
      解题思路
      使用深度优先搜索(DFS)和回溯法:
      使用递归函数 dfsPartition,从字符串的起始位置开始尝试分割。
      对于每个可能的分割点,检查当前子字符串是否为回文。
      如果是回文,则将其加入当前路径,并递归处理剩余部分。
      如果到达字符串末尾且所有子字符串均为回文,则将当前路径加入结果列表。

//131. 分割回文串
public List<List> partition(String s) {
List<List> res = new ArrayList<>();
LinkedList stack = new LinkedList<>();
dfsPartition(res, stack, s, 0);
return res;
}
private void dfsPartition(List<List> res,LinkedList stack,String s,int start){
if (starts.length()){
res.add(new ArrayList<>(stack));
return;
}
for (int i=1; start+i<=s.length(); i++){//i决定截取字符串的长度
//左闭右开
String str=s.substring(start,start+i);
if (!isPalindrome(str)) continue;
//在 Java 的 LinkedList 中,push 方法是将元素添加到栈顶(即链表的头部),而 pop 方法是从栈顶(链表头部)移除元素。
//因此如果使用栈的操作会导致内部集合的元素顺序相反。
stack.add(str);
dfsPartition(res,stack,s,start+i);
stack.removeLast();
}
}
private boolean isPalindrome(String s) {
if (s.length()
1) return true;
int left =0,right=s.length()-1;
while (left<right){
if (s.charAt(left)!=s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
注意点:回溯使用 stack.add 和 stack.removeLast,避免使用 push 和 pop 导致顺序问题。
在 Java 的 LinkedList 中,push 方法是将元素添加到栈顶(即链表的头部),而 pop 方法是从栈顶(链表头部)移除元素。

    1. 组合总和 II
      问题描述
      给定一个数组 candidates 和一个目标值 target,找出数组中所有和为目标值的组合。数组中的数字可以重复使用,但每个数字只能使用一次。
      解题思路
      对数组进行排序,便于去重。
      使用深度优先搜索(DFS)和回溯法:
      从当前索引开始,尝试选择每个数字。
      如果当前路径的和等于目标值,则将其加入结果列表。
      跳过重复的数字,避免重复组合。
      使用全局变量 sum2 记录当前路径的和。
      注意点
      去重:通过 if (i > start && candidates[i] == candidates[i - 1]) continue 跳过重复的数字。
      提前终止:如果当前路径的和超过目标值,直接返回。
      全局变量:使用 sum2 记录当前路径的和,但需要在递归前后正确更新其值。
      //40. 组合总和 II
      private int sum2=0;
      public List<List> combinationSum2(int[] candidates, int target) {
      Arrays.sort(candidates);
      List<List> res = new ArrayList<>();
      if(candidates.length0) return res;
      LinkedList stack = new LinkedList<>();
      dfsCombinationSum2(candidates,target,res,stack,0);
      return res;
      }
      private void dfsCombinationSum2(int[] candidates, int target, List<List> res,LinkedList stack,int start) {
      if (sum2
      target) {
      res.add(new ArrayList<>(stack));
      return;
      }
      if(stack.size()candidates.length) return;
      for(int i=start; i<candidates.length; i++) {
      if(i>start && candidates[i]
      candidates[i-1]) continue;
      if(sum2+candidates[i]>target) return;
      sum2+=candidates[i];
      stack.push(candidates[i]);
      dfsCombinationSum2(candidates, target, res, stack, i+1);
      sum2-=candidates[i];
      stack.pop();
      }
      }
    1. 组合总和
      问题描述
      给定一个数组 candidates 和一个目标值 target,找出数组中所有和为目标值的组合。数组中的数字可以重复使用。
      解题思路
      对数组进行排序(可选,但有助于剪枝)。
      使用深度优先搜索(DFS)和回溯法:
      从当前索引开始,尝试选择每个数字。
      如果当前路径的和等于目标值,则将其加入结果列表。
      如果当前路径的和超过目标值,则提前终止。
      允许重复使用当前数字,因此递归时传递相同的索引。
      注意点
      剪枝:如果当前路径的和超过目标值,直接返回。
      重复使用数字:递归时传递相同的索引 i,允许重复使用当前数字。
      回溯:使用 stack.push 和 stack.pop 管理当前路径。
      //39. 组合总和
      public List<List> combinationSum(int[] candidates, int target) {
      Arrays.sort(candidates);
      List<List> result = new ArrayList<>();
      if(candidates.length == 0) return result;
      LinkedList stack = new LinkedList<>();
      dfCombinationSum(candidates,target,result,stack,0,0);
      return result;
      }
      private void dfCombinationSum(int[] candidates, int target,List<List> result, LinkedList stack,int sum,int start) {
      if (sum == target) {
      result.add(new ArrayList<>(stack));
      return;
      } else if (sum>target) {
      return;
      }
      for (int i =start; i < candidates.length; i++) {
      if(sum+candidates[i]>target) return;
      stack.push(candidates[i]);
      dfCombinationSum(candidates, target, result, stack, sum+candidates[i],i);
      stack.pop();
      }
      }

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】20250215

我只懂得一种活法,那就是找一件事坚持下去,以战胜生命的虚无。【每日一题】(多选)实验表明,可见光通过三棱镜时各色光的折射率 \(n\) 随着波长 \(\lambda\) 的变化符合科西经验公式,\(n=A+\frac{B}{\lambda^2}+\frac{C}{\lambda^4}\),其中 \(A\)、\(B\)、\(C\) 是正的常…

用IRFZ44N MOS管制作一个开关电路并测试其导通电压

用IRFZ44N NMOS管当开关管,设计一个开关电路,控制小灯泡的亮灭 下面是电路图,小灯泡大小为24V 10W图中R1是泄放电阻,因为GS间有结电容,如果没有加R1,在V2关断时,小灯泡不会立即熄灭,还会维持很长一段时间,明显不合理。 相比于三极管,MOS管能够承载的电流更大,更适用…

撑起计算机视觉半边天的ResNet【论文精读】

ResNet论文精读:深度残差学习如何重塑深度学习一、技术演进背景:深度网络的困境与突破 消失的梯度与退化问题 在ResNet提出之前,深度学习领域已通过VGGNet、GoogLeNet等模型验证了网络深度的重要性。然而,当网络深度超过20层时,研究者发现了一个反直觉现象:更深的网络反而…

2025多校冲刺省选模拟赛13

2025多校冲刺省选模拟赛13\(T1\) A. 逆序对 \(56pts\)原题: luogu P5972 [PA 2019] Desant部分分\(56pts\) :爆搜。点击查看代码 int a[50]; pair<int,ll>ans[50]; struct BIT {int c[50];int lowbit(int x){return x&(-x);}void add(int x,int val){for(int i=x;i…

使用 Git 命令和 Github 前须了解的知识

本文不包括 Git 命令的介绍与使用,只分享 Git 的关键概念与 Github 项目的基本工作流程。作者相信先了解它们对后续的学习和工作大有裨益。(如有错误和建议请大家评论告知)版本控制系统 VCS → Version Control System,版本控制系统 → 一个跟踪文件变化、记录修订情况、协…

leetcode hot 02

解题思路:找祖先从底向上递归后序遍历查找,遇到p,q或者空节点就直接返回对应值,当某个节点的左子树、右子树都返回了值,那么就说明该节点就是最近祖先节点,然后把该节点的值继续往上传,直到根节点返回结果。 /*** Definition for a binary tree node.* public class Tre…

Linux介绍及使用

一、linux介绍 1、Linux是一个免费、开源的操作系统,能多用户、多任务、支持多线程和多CPU的操作系统,相对windows更加稳定,在unix系统的基础上开发的系统; 注解:(1)免费:不要钱 (2)源代码公开 (3)多用户 :可以在不同用户操作 (4)多任务:同时执行多个任务 …

Maven 生命周期 Test 阶段遇到的一些问题

Q:无法使用@Test注解,报错 A:最初pom.xml中使用的Junit版本为3,Java 5于 2004 年发布,引入了注解作为语言的一部分。而Junit 3 是在这之前发布的,因此它无法使用注解,将pom.xml中的版本号改为<version>4.13.2</version>后问题解决,可使用@TestQ:在Maven启…

18. 信号

一、什么是信号在 Linux 中,信号是一种用于通知进程发生了某种事件的机制。信号可以由内核、其它进程或者命令行工具发送给目标进程。Linux 系统中由多种信号,每种信号都用一个唯一的数值表示。例如,常见的信号如下:SIGINT (2):这是当用户在终端按下 Ctrl+C 时发送给前台进…

【专题】DeepSeek技术颠覆or创新共赢,开启Al算法变革元年报告汇总PDF洞察(附原数据表)

原文链接: https://tecdat.cn/?p=39544 在科技飞速迭代的当下,人工智能领域正经历着深刻变革,AI Agent 的发展尤为引人瞩目。 随着数字化进程的加速,全球数据量呈指数级增长,如同为 AI Agent 的发展提供了丰沃土壤。海量数据不仅为模型训练提供了坚实基础,更驱动着 AI A…