算法解题:挑战与技巧

题目

选自力扣

判断是否可以赢得数字游戏

给你一个 正整数 数组 nums。

Alice 和 Bob 正在玩游戏。在游戏中,Alice 可以从 nums 中选择所有个位数 或 所有两位数,剩余的数字归 Bob 所有。如果 Alice 所选数字之和 严格大于 Bob 的数字之和,则 Alice 获胜。

如果 Alice 能赢得这场游戏,返回 true;否则,返回 false。

示例 1:

输入:nums = [1,2,3,4,10]

输出:false

解释:

Alice 不管选个位数还是两位数都无法赢得比赛。

示例 2:

输入:nums = [1,2,3,4,5,14]

输出:true

解释:

Alice 选择个位数可以赢得比赛,所选数字之和为 15。

示例 3:

输入:nums = [5,5,5,25]

输出:true

解释:

Alice 选择两位数可以赢得比赛,所选数字之和为 25。

提示:

1 <= nums.length <= 100
1 <= nums[i] <= 99

public class Driver {

    public static boolean canAliceWin( int[] nums) {
        int oneDigitSum = 0;
        int twoDigitSum = 0;

        for (int num : nums) {
            if (num >= 1 && num <= 9) {
                oneDigitSum += num;
            } else if (num >= 10 && num <= 99) {
                twoDigitSum += num;
            }
        }

        // 判断 Alice 选择个位数能否赢
        boolean winWithOneDigit = oneDigitSum > twoDigitSum;
        // 判断 Alice 选择两位数能否赢
        boolean winWithTwoDigits = twoDigitSum > oneDigitSum;

        // 如果 Alice 选择个位数能赢或选择两位数能赢,则返回 true
        return winWithOneDigit || winWithTwoDigits;
    }

    public static void main(String[] args) {
        int[] nums1 = {1, 2, 3, 4, 10};
        System.out.println(canAliceWin(nums1)); // 输出: false

        int[] nums2 = {1, 2, 3, 4, 5, 14};
        System.out.println(canAliceWin(nums2)); // 输出: true

        int[] nums3 = {5, 5, 5, 25};
        System.out.println(canAliceWin(nums3)); // 输出: true
    }
}

2给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

提示:

root 树上的节点数量范围是 [1, 2000]
subRoot 树上的节点数量范围是 [1, 1000]
− 1 0 4 < = r o o t . v a l < = 1 0 4 -10^4 <= root.val <= 10^4 104<=root.val<=104
− 1 0 4 < = s u b R o o t . v a l < = 1 0 4 -10^4 <= subRoot.val <= 10^4 104<=subRoot.val<=104

要解决这个问题,我们可以采用递归的方式来比较两棵树是否相同,以及寻找主树 (root) 中是否存在与子树 (subRoot) 相同的子树。具体来说,我们需要实现两个主要的功能:

  1. isSameTree:检查两棵树是否完全相同。
  2. findSubTree:在主树中查找与子树相同的子树。

下面是具体的实现方法:

Java 实现

首先,我们需要定义二叉树的节点结构:

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;
    }
}

接下来,我们实现主要的逻辑:

public class Solution {

    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if (root == null && subRoot != null) return false;
        if (root != null && subRoot == null) return false;
        if (root == null && subRoot == null) return true;
        
        // 检查当前节点是否匹配
        if (root.val == subRoot.val) {
            if (isSameTree(root, subRoot)) {
                return true;
            }
        }
        
        // 递归检查左子树和右子树
        return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
    }

    private boolean isSameTree(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) return true;
        if (t1 == null || t2 == null) return false;
        if (t1.val != t2.val) return false;
        return isSameTree(t1.left, t2.left) && isSameTree(t1.right, t2.right);
    }

    public static void main(String[] args) {
        // 构建示例中的树
        TreeNode root = new TreeNode(3,
                new TreeNode(4,
                        new TreeNode(1),
                        new TreeNode(2)),
                new TreeNode(5));

        TreeNode subRoot = new TreeNode(4,
                new TreeNode(1),
                new TreeNode(2));

        Solution solution = new Solution();
        boolean result = solution.isSubtree(root, subRoot);
        System.out.println(result); // 输出: true
    }
}

解释

  1. isSubtree 方法:这个方法用来递归地检查 root 中是否存在与 subRoot 相同的子树。它首先检查根节点是否匹配,然后递归地检查左右子树。

  2. isSameTree 方法:这个辅助方法用来检查两棵树是否完全相同。它递归地比较两棵树的每个节点。

测试

你可以使用提供的示例来测试这段代码,或者构建自己的测试用例。注意,你需要根据实际输入构建相应的二叉树结构。如果你需要帮助构建测试用例,请告诉我,我可以进一步协助你。
`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

布说在见

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

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

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

打赏作者

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

抵扣说明:

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

余额充值