代码编织梦想

39. 组合总和

力扣链接

思路

回溯,同一个元素可以重复取,那调用的时候就传自己进去。数组递增,所以当加起来的和大于target就可以返回了。

代码

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    int sum=0;
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        find(candidates,target,0);
        return result;
    }

    public void find(int[] candidates, int target,int startIndex){
        if(sum>target) return;
        if(sum==target){
            result.add(new ArrayList<>(path));
            return;
        }

        for(int i=startIndex;i<candidates.length;i++){
            path.add(candidates[i]);
            sum+=candidates[i];
            find(candidates,target,i);
            path.remove(path.size()-1);
            sum-=candidates[i];
        }
    }
}

40.组合总和II

力扣链接

思路

回溯,给的数组不是递增,所以要调用一下库函数排序(1.方便确认返回条件 2.可以避免取到重复组合)跟上面不一样的元素不能重复取,但是它可以提供重复元素(通过标记函数是否使用过,来剪枝。排序后,当前元素如果与前一个元素相同,并且前一个元素没有处于被使用状态,那就continue【因为我们取元素是往后取的,前一个元素没有被使用就相当于,当前元素的组合肯定和前一个元素组合相同,不是两个元素同时取的情况】)

代码

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    int[] haveUsed;
    int sum=0;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        haveUsed=new int[candidates.length];
        Arrays.sort(candidates);
        find(candidates,target,0);
        return result;
    }

    public void find(int[] candidates, int target,int startIndex){
        if(sum==target){
            result.add(new ArrayList<>(path));
            return;
        }

        for(int i=startIndex;i<candidates.length;i++){
            if(sum+candidates[i]>target) break;
            if(i>0 && candidates[i]==candidates[i-1] && haveUsed[i-1]==0) continue;
            path.add(candidates[i]);
            sum+=candidates[i];
            haveUsed[i]=1;
            find(candidates,target,i+1);
            path.removeLast();
            sum-=candidates[i];
            haveUsed[i]=0;
        }
    }
}

131.分割回文串

力扣链接

思路

回溯,与上面不同的是,传的是固定的数组,但是这里传的是分割后的字符串,是一直在改变的,把startindex看作是隔板,一直划分。

代码

class Solution {
    List<List<String>> result=new ArrayList<>();
    List<String> pathList=new ArrayList<>();
    String path="";
    public List<List<String>> partition(String s) {
        find(s,0);
        return result;
    }

    public void find(String s,int startIndex){
        if(startIndex>=s.length()){
            result.add(new ArrayList<>(pathList));
        }

        for(int i=startIndex;i<s.length();i++){
            int len=path.length();
            path=s.substring(startIndex,i+1);
            if(!charge(path)) continue;
            pathList.add(path);
            find(s,i+1);
            pathList.remove(pathList.size()-1);
        }
    }

    public boolean charge(String s){
        int left=0;
        int right=s.length()-1;
        while(left<=right){
            if(s.charAt(left)!=s.charAt(right)) return false;
            left++;
            right--;
        }
        return true;
    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_73799676/article/details/140754140

算法训练day27|leetcode 39. 组合总和、40.组合总和ii、131.分割回文串-爱代码爱编程

题目链接:39. 组合总和 class Solution { private: vector<vector<int>> result; vector<int> path; void backtracking(vector<int>& candidates, int tar

day27|leetcode 39. 组合总和、40.组合总和ii、131.分割回文串-爱代码爱编程

leetcode 39. 组合总和 题目链接:39. 组合总和 - 力扣(LeetCode) 视频链接:带你学透回溯算法-组合总和(对应「leetcode」力扣题目:39.组合总和)| 回溯法精讲!_哔哩哔哩_bilibili 题目概述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candida

day27|leetcode 39. 组合总和 leetcode 40. 组合总和 ii leetcode131. 分割回文串-爱代码爱编程

Leetcode 39. 组合总和 题目链接 39 组合总和 本题目和前面的组合问题差不多,只不过这里能重复选取数字,还是要注意组合的定义,交换数字顺序还是算一个组合,所以这里还是用我们的startIndex来记录取的数字到哪里了,下面上代码: class Solution { private: vector<int> p

算法训练营第47天|1143.最长公共子序列|1035.不相交的线|53. 最大子序和|392.判断子序列-爱代码爱编程

1143.最长公共子序列 思路:这道题比较难理解的是递推公式,要想明白状态转换和各个状态的意义。 如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1; 如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1

【算法】字典序最小的 01 字符串-爱代码爱编程

字典序最小的 01 字符串 题目描述 小红有一个 01 字符串,她可以进行最多 k 次提作,每次操作可以交换相邻的两个字符,问可以得到的字典序最小的字符串是什么。 输入描述 第一行包含两个整数,n(1 < n

2766. 重新放置石块 medium-爱代码爱编程

给你一个下标从 0 开始的整数数组 nums ,表示一些石块的初始位置。再给你两个长度 相等 下标从 0 开始的整数数组 moveFrom 和 moveTo 。 在 moveFrom.length 次操作内,你可以改变石块的位置。在第 i 次操作中,你将位置在 moveFrom[i] 的所有石块移到位置 moveTo[i] 。 完成这些操作后,请你按升

贪心加暴力枚举-爱代码爱编程

数据范围只有 1 0

学习记录day18——数据结构 算法-爱代码爱编程

算法的相关概念         程序 = 数据结构 + 算法 算法是程序设计的灵魂,结构式程序设计的肉体 算法:计算机解决问题的方法护额步骤 算法的特性 1、确定性:算法中每一条语句都有确定的含义,不能模棱两可 2、有穷性:程序执行一段时间后会自动结束 3、输入:有零个或多个输入 4、输出:至少一个输出,可输出多个 5、可行性:经济可行性

codeforces round 961 (div. 2)-爱代码爱编程

A题:Diagonals 题意 给定一个n x n的网格,k个筹码,放在某个位置,则其对应的右上-左下对角线被占用,问占用的对角线数量最少是多少? 思路 模拟 每次我们都往格子最多的对角线上放,然后次多... 很容易看出来 代码 inline void solve() { int n, k; cin >> n >

1137. 第 n 个泰波那契数-爱代码爱编程

1137. 第 N 个泰波那契数 题目链接:1137. 第 N 个泰波那契数 代码如下: class Solution { public: int tribonacci(int n) {

算法刷题day20|回溯:39. 组合总和、40. 组合总和 ii、131. 分割回文串-爱代码爱编程

39. 组合总和 回溯 class Solution { private: vector<vector<int>> result; vector<int> path; void backtracking(vector<int>& candidates, int targ

代码随想录算法训练营day6 | 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1.两数之和-爱代码爱编程

文章目录 哈希表键值 哈希函数哈希冲突拉链法线性探测法 常见的三种哈希结构集合映射C++实现std::unordered_setstd::map 小结242.有效的字母异位词思

24暑假算法刷题 | day23 | leetcode 39. 组合总和,40. 组合总和 ii,131. 分割回文串-爱代码爱编程

目录 39. 组合总和题目描述题解 40. 组合总和 II题目描述题解 131. 分割回文串题目描述题解 39. 组合总和 点此跳转题目链接 题目描述 给你一个 无重复元素