LeetCode刷题 day33

目录

1.预测赢家

给你一个整数数组 nums 。玩家 1 和玩家 2 基于这个数组设计了一个游戏。

玩家 1 和玩家 2 轮流进行自己的回合,玩家 1 先手。开始时,两个玩家的初始分值都是 0 。每一回合,玩家从数组的任意一端取一个数字(即,nums0 或 numsnums.length - 1),取到的数字将会从数组中移除(数组长度减 1 )。玩家选中的数字将会加到他的得分上。当数组中没有剩余数字可取时,游戏结束。

如果玩家 1 能成为赢家,返回 true 。如果两个玩家得分相等,同样认为玩家 1 是游戏的赢家,也返回 true 。你可以假设每个玩家的玩法都会使他的分数最大化。

示例 1:

输入:nums = 1,5,2

输出:false

解释:一开始,玩家 1 可以从 1 和 2 中进行选择。

如果他选择 2(或者 1 ),那么玩家 2 可以从 1(或者 2 )和 5 中进行选择。如果玩家 2 选择了 5 ,那么玩家 1 则只剩下 1(或者 2 )可选。

所以,玩家 1 的最终分数为 1 + 2 = 3,而玩家 2 为 5 。

因此,玩家 1 永远不会成为赢家,返回 false 。

示例 2:

输入:nums = 1,5,233,7

输出:true

解释:玩家 1 一开始选择 1 。然后玩家 2 必须从 5 和 7 中进行选择。无论玩家 2 选择了哪个,玩家 1 都可以选择 233 。

最终,玩家 1(234 分)比玩家 2(12 分)获得更多的分数,所以返回 true,表示玩家 1 可以成为赢家。

思路

递归

每名玩家都想办法让自己赢,在尝试所有情况下后如果还是无法获胜,则表明自己必输,否则按照能获胜的方式去尝试。玩家一有主动权,只要有一种情况能获胜即可。

java 复制代码
class Solution {
    public boolean predictTheWinner(int[] nums) {
        return firstHand(nums,0,nums.length-1,0,0);
    }
    //玩家一
    //尽最大努力让自己赢
    private boolean firstHand(int[] nums,int start,int end,int t1,int t2){
        if(start>end){
            return t1>=t2;
        }
        //两种可能,选左
        t1+=nums[start];
        if(!secondHand(nums,start+1,end,t1,t2)){
            return true;
        }
        //选右
        t1-=nums[start];
        t1+=nums[end];
        if(!secondHand(nums,start,end-1,t1,t2)){
            return true;
        }
        return false;
    }
    //玩家二
    private boolean secondHand(int[] nums,int start,int end,int t1,int t2){
        if(start>end){
            return t2>t1;
        }
        t2+=nums[start];
        if(!firstHand(nums,start+1,end,t1,t2)){
            return true;
        }
        t2-=nums[start];
        t2+=nums[end];
        if(!firstHand(nums,start,end-1,t1,t2)){
            return true;
        }
        return false;
    }
}

时间复杂度: O ( 2 n ) O(2^n) O(2n)

空间复杂度: O ( n ) O(n) O(n)

动态规划

使用二维数组dpnn,dpij表示取值范围为i,j范围内时,当前选手得分与另一个选手得分差值。

当i=j时,当前玩家只有一种选择,即numsi,此时dpii = numsi

当i<j时,当前玩家可以选择numsi或者numsj,以使得自己得分的最大化,即

dpij = max{numsi-dpi+1j,numsj+dpij-1}

最后判断dp0n-1是否大于等于0即可

java 复制代码
class Solution {
    public boolean predictTheWinner(int[] nums) {
        int n = nums.length;
        int[][] dp = new int[n][n];
        for(int i=0;i<n;i++){
            dp[i][i] = nums[i];
        }
        for(int i=n-1;i>=0;i--){
            for(int j=i+1;j<n;j++){
                dp[i][j] = Math.max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]);
            }
        }
        return dp[0][n-1]>=0;
    }
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

空间复杂度: O ( n 2 ) O(n^2) O(n2) 若优化动态规划空间的话,空间复杂度为 O ( n ) O(n) O(n)

2. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

只使用数字1到9

每个数字 最多使用一次

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:

输入: k = 3, n = 7

输出: \[1,2,4]

解释:

1 + 2 + 4 = 7

没有其他符合的组合了。

示例 2:

输入: k = 3, n = 9

输出: \[1,2,6, 1,3,5, 2,3,4]

解释:

1 + 2 + 6 = 9

1 + 3 + 5 = 9

2 + 3 + 4 = 9

没有其他符合的组合了。

示例 3:

输入: k = 4, n = 1

输出: \[\]

解释: 不存在有效的组合。

1,9范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

思路

递归

java 复制代码
class Solution {
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        dfs(9,n,k);
        return ans;
    }
    private void dfs(int n,int leftSum,int d){
        if(leftSum<0||leftSum>(n*2-d+1)*d/2){
            return ;
        }
        if(d==0&&leftSum==0){
            ans.add(new ArrayList<>(path));
            return ;
        }
        for(int j=n;j>0;j--){
            path.add(j);
            dfs(j-1,leftSum-j,d-1);
            path.removeLast();
        }
    }
    
}
相关推荐
就叫_这个吧3 小时前
Java递归方法实现面包屑导航
java·开发语言
小O的算法实验室3 小时前
IEEE TASE,基于MPC的多无人机协同搜索竞争群体优化方法
算法
fīɡЙtīиɡ ℡3 小时前
AI 应用系统设计
java·开发语言·人工智能
小飞学编程...3 小时前
【哈希表】
数据结构·哈希算法·散列表
城管不管3 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
码匠许师傅3 小时前
【C++ 面试真题】26. 聊聊 C++ 的智能指针
java·c++·面试
AI绘画哇哒哒3 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
Tbisnic4 小时前
BGE-M3 算法详解:从模型架构到三种检索方式的数学原理
算法·自然语言处理·大模型·bert·transformer·注意力机制
最强小杰4 小时前
gpt-5.6-sol 频繁报 503 怎么办?区分容量熔断和限速 429 的排查方法 + 可复用 retry wrapper
java·人工智能·gpt·ai
Brilliantwxx4 小时前
【算法从零到千】【55-58】哈希位图+常见数学运算 接口
算法