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();
        }
    }
    
}
相关推荐
都叫我大帅哥2 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-2 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常3 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅3 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
luj_17683 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
xcLeigh4 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang
AI大模型-小华4 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
Mark_ZP4 小时前
【锁1】Synchronized vs ReentrantLock区别
java
木木子225 小时前
# 鸿蒙 ArkTS 实战:秒表 Stopwatch(示例 5)
数据结构·华为·list·harmonyos
立心者05 小时前
SpringBoot中使用TOTP实现MFA(多因素认证)
java·spring boot·后端