侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 471 篇文章
  • 累计创建 108 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【模拟, 递归】极大极小游戏

GabrielxD
2022-06-05 / 0 评论 / 0 点赞 / 30 阅读 / 624 字 / 正在检测是否收录...

题目

6090. 极大极小游戏


给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。

nums 执行下述算法:

  • n 等于 nums 的长度,如果 n == 1 ,终止 算法过程。否则,创建 一个新的整数数组 newNums ,新数组长度为 n / 2 ,下标从 0 开始。
  • 对于满足 0 <= i < n / 2 的每个 偶数 下标 i ,将 newNums[i] 赋值 为 min(nums[2 * i], nums[2 * i + 1])
  • 对于满足 0 <= i < n / 2 的每个 奇数 下标 i ,将 newNums[i] 赋值 为 max(nums[2 * i], nums[2 * i + 1])
  • newNums 替换 nums
  • 从步骤 1 开始 重复 整个过程。

执行算法后,返回 nums 中剩下的那个数字。

示例 1:

image-20220605185948303

输入:nums = [1,3,5,2,4,8,2,2]
输出:1
解释:重复执行算法会得到下述数组。
第一轮:nums = [1,5,4,2]
第二轮:nums = [1,4]
第三轮:nums = [1]
1 是最后剩下的那个数字,返回 1 。

示例 2:

输入:nums = [3]
输出:3
解释:3 就是最后剩下的数字,返回 3 。

提示:

  • 1 <= nums.length <= 1024
  • 1 <= nums[i] <= 109
  • nums.length2 的幂

解题

方法一:模拟

思路

根据题意模拟即可。

代码

class Solution {
    public int minMaxGame(int[] nums) {
        while (nums.length != 1) {
            int newLen = nums.length / 2;
            int[] newNums = new int[newLen];
            for (int i = 0; i < newLen; i++) {
                if ((i & 1) == 0) {
                    newNums[i] = Math.min(nums[2 * i], nums[2 * i + 1]);
                } else {
                    newNums[i] = Math.max(nums[2 * i], nums[2 * i + 1]);
                }
            }
            nums = newNums;
        }
        return nums[0];
    }
}

优化

因为数组的有效长度在逐渐减小,而且生成新数组用到原数组里的元素索引是有序的,那么就可以不创建新数组,直接在原数组上进行修改,仅维护一个有效长度(n)就行。

class Solution {
    public int minMaxGame(int[] nums) {
        int n = nums.length;
        while (n != 1) {
            n /= 2;
            for (int i = 0; i < n; i++) {
                nums[i] = (i & 1) == 0 ?
                    Math.min(nums[2 * i], nums[2 * i + 1]) :
                    Math.max(nums[2 * i], nums[2 * i + 1]);
            }
        }
        return nums[0];
    }
}

方法二:递归

思路

可以把循环改成递归。

代码

class Solution {
    private int[] nums;
    
    public int minMaxGame(int[] _nums) {
        nums = _nums;
        return dfs(nums.length);
    }

    private int dfs(int len) {
        if (len == 1) return nums[0];
        int newLen = len / 2;
        for (int i = 0; i < newLen; i++) {
            nums[i] = (i & 1) == 0 ?
                Math.min(nums[2 * i], nums[2 * i + 1]) :
                Math.max(nums[2 * i], nums[2 * i + 1]);
        }
        return dfs(newLen);
    }
}
0

评论区