leetcode 2210. 统计数组中峰和谷的数量

414 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

leetcode 2210. 统计数组中峰和谷的数量

给你一个下标从 0 开始的整数数组 nums 。如果两侧距 i 最近的不相等邻居的值均小于 nums[i] ,则下标 i 是 nums 中,某个峰的一部分。类似地,如果两侧距 i 最近的不相等邻居的值均大于 nums[i] ,则下标 i 是 nums 中某个谷的一部分。对于相邻下标 i 和 j ,如果 nums[i] == nums[j] , 则认为这两下标属于 同一个 峰或谷。

注意,要使某个下标所做峰或谷的一部分,那么它左右两侧必须 都 存在不相等邻居。

返回 nums 中峰和谷的数量。

示例 1:

输入:nums = [2,4,1,1,6,5]
输出:3
解释:
在下标 0 :由于 2 的左侧不存在不相等邻居,所以下标 0 既不是峰也不是谷。
在下标 1 :4 的最近不相等邻居是 2 和 1 。由于 4 > 2 且 4 > 1 ,下标 1 是一个峰。
在下标 2 :1 的最近不相等邻居是 4 和 6 。由于 1 < 4 且 1 < 6 ,下标 2 是一个谷。
在下标 3 :1 的最近不相等邻居是 4 和 6 。由于 1 < 4 且 1 < 6 ,下标 3 符合谷的定义,但需要注意它和下标 2 是同一个谷的一部分。
在下标 4 :6 的最近不相等邻居是 1 和 5 。由于 6 > 1 且 6 > 5 ,下标 4 是一个峰。
在下标 5 :由于 5 的右侧不存在不相等邻居,所以下标 5 既不是峰也不是谷。
共有 3 个峰和谷,所以返回 3 。

示例 2:

输入:nums = [6,6,5,5,4,1]
输出:0
解释:
在下标 0 :由于 6 的左侧不存在不相等邻居,所以下标 0 既不是峰也不是谷。
在下标 1 :由于 6 的左侧不存在不相等邻居,所以下标 1 既不是峰也不是谷。
在下标 2 :5 的最近不相等邻居是 6 和 4 。由于 5 < 6 且 5 > 4 ,下标 2 既不是峰也不是谷。
在下标 3 :5 的最近不相等邻居是 6 和 4 。由于 5 < 6 且 5 > 4 ,下标 3 既不是峰也不是谷。
在下标 4 :4 的最近不相等邻居是 5 和 1 。由于 4 < 5 且 4 > 1 ,下标 4 既不是峰也不是谷。
在下标 5 :由于 1 的右侧不存在不相等邻居,所以下标 5 既不是峰也不是谷。 共有 0 个峰和谷,所以返回 0 。  

提示:

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

解题思路

根据题意我们可以了解如果一个元素左右俩测都大于此元素的话就说明是个谷,反之一个元素左右俩测都小于此元素的话就说明是个峰。当然如果存在相邻些元素相等,但存在俩测都大于或都小于那么就属于同一峰谷。

结合上述所说我们可以先通过循环找到俩测与当前元素大小不一样的,然后再去判断是否是同大或者同小。当然我们需要判断当前元素与前一个元素是否相同,如果相同的话说明是同一峰谷。

分步实现

定义ans变量用于存在峰谷数量,通过for循环试着找出每一个元素是否存在峰谷。

let ans = 0;
for (let i = 1; i < nums.length - 1; i++) {
}

如果在i不等于1的情况下,存在nums[i] == nums[i-1]就说明是同峰谷,再之前已经计算过了使用continue跳出本次循环。

let ans = 0;
for (let i = 1; i < nums.length - 1; i++) {
    if(nums[i] == nums[i-1] && i!==1) continue
}

定义j用于存放左侧与当前不一样的元素的下标,k用于存放右侧与当前不一样的元素的下标。

let ans = 0;
for (let i = 1; i < nums.length - 1; i++) {
    if(nums[i] == nums[i-1] && i!==1) continue
    let j = i - 1;
    let k = i + 1;
    while (j >= 0 && nums[j] === nums[i]) {
        j--;
    }
    while (k < nums.length && nums[k] === nums[i]) {
        k++;
    }
}

如果左右侧同时大于或小于当前值就说明是存在峰谷的,ans++。

let ans = 0;
for (let i = 1; i < nums.length - 1; i++) {
    if(nums[i] == nums[i-1] && i!==1) continue
    let j = i - 1;
    let k = i + 1;
    while (j >= 0 && nums[j] === nums[i]) {
        j--;
    }
    while (k < nums.length && nums[k] === nums[i]) {
        k++;
    }
    if ((nums[j] < nums[i] && nums[k] < nums[i]) 
            || (nums[j] > nums[i] && nums[k] > nums[i])
    ) {
          ans++;
    }
}

代码实现

/**
 * @param {number[]} nums
 * @return {number}
 */
var countHillValley = function (nums) {
    let ans = 0;
    for (let i = 1; i < nums.length - 1; i++) {
        if(nums[i] == nums[i-1] && i!==1) continue
        let j = i - 1;
        let k = i + 1;
        while (j >= 0 && nums[j] === nums[i]) {
            j--;
        }
        while (k < nums.length && nums[k] === nums[i]) {
            k++;
        }
        if ((nums[j] < nums[i] && nums[k] < nums[i]) 
            || (nums[j] > nums[i] && nums[k] > nums[i])
        ) {
            ans++;
        }
    }
    return ans;
};