【力扣刷题】747. 至少是其他数字两倍的最大数

352 阅读1分钟

「这是我参与11月更文挑战的第 6 天,活动详情查看:2021最后一次更文挑战

原题链接

747. 至少是其他数字两倍的最大数 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一个整数数组 nums ,其中总是存在 唯一的 一个最大整数 。

请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 。如果是,则返回 最大元素的下标 ,否则返回 -1 。

测试用例

示例 1:

输入:nums = [3,6,1,0]
输出:1
解释:6 是最大的整数,对于数组中的其他整数,6 大于数组中其他元素的两倍。6 的下标是 1 ,所以返回 1 。

示例 2:

输入:nums = [1,2,3,4]
输出:-1
解释:4 没有超过 3 的两倍大,所以返回 -1 。

参数限制

  • 1 <= nums.length <= 50
  • 0 <= nums[i] <= 100
  • nums 中的最大元素是唯一的

分析

题目描述有点绕,换个说法,我们需要找到最大的两个数,需要判断最大的数是否为次大的数的 2 倍。

最简单的做法,就是对整个数组进行倒序排列,判断 arr[0] 是否位 arr[1] 的值的 2 倍即可

代码

var dominantIndex = function(nums) {
    if(nums.length==1)return 0;
    let arr = [...nums].sort((a,b)=>b-a);
    return arr[0] >= arr[1] * 2?nums.indexOf(arr[0]):-1;
};

虽然解决了问题,但其中存在多余的操作,我们只需要其中最大的 2 个数,但这个操作把其他我们完全用不到的数也全部排列好了,占用了一定的时间

优化

我们定义一个结构来辅助记录两个最大的数,在原数组遍历完成后,我们已经记录好了最大数的值和下标,以及次大数的值,只需要判断是返回坐标还是返回 -1

var dominantIndex = function(nums) {
    if (nums.length == 1) return 0;
    let arr = new limitSortArr();
    nums.forEach((n, i) => arr.add(n, i));
    return arr.arr[0] >= arr.arr[1] * 2 ? arr.getI() : -1;

    function limitSortArr() {
        let arr = [0, 0];
        let index = -1;
        return {
            add(n, i) {
                if (n <= arr[1]) return;
                if (n > arr[0]) {
                    arr[1] = arr[0];
                    arr[0] = n;
                    index = i;
                } else {
                    arr[1] = n;
                }
            },
            getI:()=> index,
            arr: arr
        }
    }
};

image.png

今天的力扣刷题就分享到这里,感谢大家的阅读~