【每日力扣】40.组合总和II与701. 二叉搜索树中的插入操作

文章讲述了如何使用回溯算法解决组合总和II问题,即找出给定数组中所有和为目标数的组合,并介绍了在二叉搜索树中插入新值的方法,确保插入后仍保持二叉搜索树的特性。
摘要由CSDN通过智能技术生成

在这里插入图片描述

🔥 个人主页: 黑洞晓威
😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害。

40.组合总和II

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次

**注意:**解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

问题分析

首先,我们需要明确题目中的要求和限制条件:

  • 给定一个正整数数组 candidates 和一个目标数 target
  • 数组中的每个数字在每个组合中只能使用一次。
  • 解集不能包含重复的组合。

我们需要找出所有满足条件的组合,将它们以列表形式返回。

解题思路

  1. 排序数组:为了方便后续的剪枝操作和去重操作,我们首先对数组进行排序。

  2. 回溯搜索:使用回溯算法进行搜索,定义一个回溯函数 backtrack,参数包括当前的目标数 target、搜索起始位置 start、当前组合路径 path 和结果列表 result

  3. 搜索过程

    :在回溯函数中,我们逐个遍历数组中的数字,并进行如下操作:

    • 如果当前目标数为0,说明找到了一组满足条件的组合,将其加入结果列表中。
    • 如果当前目标数小于0,说明当前组合不合法,直接返回。
    • 对于每个数字,如果它和前一个数字相同且在同一层级上,则跳过,避免重复组合。
    • 否则,将当前数字加入组合路径,递归搜索下一层可能的组合,更新目标数和搜索起始位置,然后回溯移除最后一个数字,继续搜索下一个数字。
  4. 返回结果:最终返回结果列表中的所有组合。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CombinationSumII {

    public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(candidates); // 对候选数组排序,方便剪枝和去重
        backtrack(candidates, target, 0, new ArrayList<>(), result);
        return result;
    }

    private static void backtrack(int[] candidates, int target, int start, List<Integer> path, List<List<Integer>> result) {
        if (target == 0) {
            // 找到一组组合,加入结果列表中
            result.add(new ArrayList<>(path));
            return;
        }
        if (target < 0) {
            // 当前组合不合法,直接返回
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            // 避免重复组合,跳过相同的数字
            if (i > start && candidates[i] == candidates[i - 1]) {
                continue;
            }
            path.add(candidates[i]); // 将当前候选数加入组合路径
            // 递归搜索下一层可能的组合,起始位置为 i+1,因为每个数字只能使用一次
            backtrack(candidates, target - candidates[i], i + 1, path, result);
            path.remove(path.size() - 1); // 回溯,移除最后一个候选数
        }
    }

    public static void main(String[] args) {
        int[] candidates1 = {10, 1, 2, 7, 6, 1, 5};
        int target1 = 8;
        List<List<Integer>> result1 = combinationSum2(candidates1, target1);
        System.out.println(result1); // 输出 [[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]

        int[] candidates2 = {2, 5, 2, 1, 2};
        int target2 = 5;
        List<List<Integer>> result2 = combinationSum2(candidates2, target2);
        System.out.println(result2); // 输出 [[1, 2, 2], [5]]
    }
}

701. 二叉搜索树中的插入操作

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果

示例 1:

img

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:

输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:

输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

问题分析

插入操作需要考虑二叉搜索树的特性,即左子树的值小于根节点的值,右子树的值大于根节点的值。因此,在插入节点时,我们需要找到合适的位置插入,并保持树的二叉搜索树性质。

解题思路

我们可以通过递归或迭代的方式来实现插入操作。具体步骤如下:

  1. 如果根节点为空,则直接将新节点作为根节点返回。
  2. 如果要插入的值小于根节点的值,则递归插入到左子树中。
  3. 如果要插入的值大于根节点的值,则递归插入到右子树中。
  4. 最后返回根节点。
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

public class InsertIntoBST {

    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) {
            return new TreeNode(val);
        }

        if (val < root.val) {
            root.left = insertIntoBST(root.left, val);
        } else if (val > root.val) {
            root.right = insertIntoBST(root.right, val);
        }

        return root;
    }

    public static void main(String[] args) {
        // 示例用例
        TreeNode root = new TreeNode(4);
        root.left = new TreeNode(2);
        root.right = new TreeNode(7);
        root.left.left = new TreeNode(1);
        root.left.right = new TreeNode(3);
        int val = 5;

        InsertIntoBST solution = new InsertIntoBST();
        TreeNode result = solution.insertIntoBST(root, val);
        // 输出结果
        System.out.println(result);
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑洞晓威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值