力扣刷题练习 二【941.有效的山脉数组】

前言

数组题目练习。
练习二【941.有效的山脉数组】


一、题目阅读

给定一个整数数组 arr,如果它是有效的山脉数组就返回 true,否则返回 false。

让我们回顾一下,如果 arr 满足下述条件,那么它是一个山脉数组:

  • arr.length >= 3
  • 在 0 < i < arr.length - 1 条件下,存在 i 使得:
    arr[0] < arr[1] < … arr[i-1] < arr[i]
    arr[i] > arr[i+1] > … > arr[arr.length - 1]

示例 1:

输入:arr = [2,1]
输出:false

示例 2:

输入:arr = [3,5,5]
输出:false

示例 3:

输入:arr = [0,3,2,1]
输出:true

提示:

1 <= arr.length <= 104
0 <= arr[i] <= 104

二、尝试实现

思路

(1)整合题目,第一步判断size < 3,return false。

if(arr.size() < 3){
            return false;
        }

(2)考虑用双指针,用一个while循环从前往后找到山峰。

int i = 1;
int j = 0;
while(i < arr.size() && arr[i] > arr[j]){
    i++;
    j++;
}

(3)然后判断后面元素是否小于arr[j],补充count,保证至少有一个比arr[j]小。同时判断时候,考虑递减递增情况。

		int count = 0;	//count用来保证后面至少有一个元素比s[j]小。
        for(i;i < arr.size();i++){
            if(arr[i] >= arr[j]){
                break;
            }
            count++;
        }
        //j保证不是整体递减(j==0)或整体递增(j==size-1)的情况
        if(j > 0 && j < arr.size()-1 && count > 0 && i == arr.size()){	
            return true;
        }else{
            return false;
        }

(4) 但是如果出现波动就没有办法解决。比如:[1,7,9,5,4,1,2]。应该return false。但当前逻辑return true。

总结:这种思路不全面。行不通。


三、参考思路

参考思路

仍然是双指针法

  • 从两端开始移动:i == 0;j == size-1.
  • 如果arr[i] < arr [i+1],i++;如果arr[j] < arr [j-1],j–;
  • i和j能够相遇,并且大于0小于size-1,说明true。

根据参考提供思路,完成实现:

代码实现

//测试通过
class Solution {
public:
    bool validMountainArray(vector<int>& arr) {
        int size = arr.size();
        if(size < 3){
            return false;
        }
        int i = 0;
        int j = size-1;
        while(size-- && i < j ){	//size--为了不陷入死循环,最多移动也就是size,如果j,i被卡住,可以跳出循环
            if(arr[i] < arr[i+1]){
                i++;
            }
            if(arr[j-1] > arr[j]){
                j--;
            }
        }
        if(i == j && i > 0 && i < arr.size()-1){	//写成arr.size(),不能用size,因为size已经改变做--操作。
            return true;
        }else{
            return false;
        }
    }
};
  • 代码对比,改进
    (1)分别移动:当不能移动时,结束循环。
class Solution {
public:
    bool validMountainArray(vector<int>& A) {
        if (A.size() < 3) return false;
        int left = 0;
        int right = A.size() - 1;

        // 注意防止越界
        while (left < A.size() - 1 && A[left] < A[left + 1]) left++;

        // 注意防止越界
        while (right > 0 && A[right] < A[right - 1]) right--;

        // 如果left或者right都在起始位置,说明不是山峰
        if (left == right && left != 0 && right != A.size() - 1) return true;
        return false;
    }
};

四、总结

本次双指针知道用,但是用法不太正确。
从两端向中间汇聚到山顶,return true。

(欢迎指正,转载表明出处)

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值