Array126FindPeakElement

思路

思路一: 一个for loop

  • Failed cases: 并没有仔细看清楚题目要求, bigger than neighbors, 如果没有neighbours自然自己是peak啊
    • {3}
    • {3, 2, 1}
    • {1, 2, 3}

思路二: BinarySearch

核心思路是, 如果nums[n - 1] < nums[n] && nums[n] < nums[n + 1] 递增数列 那么后面肯定有peak;同理连续的递减数列. 因此可以用BinarySearch做

  • Failed Case: {1}; {1, 2} ; {2, 1}
    • peak在头尾的时候, 因为要比较neighboors会有溢出情况. 这是我刚开始的思路, 长长的第一个if条件是为了对付这个的.
    • 本来是如下的代码, 想把特殊情况放在主method里面是不对的
    public static int findPeakElementByBinarySearch(int[] nums) {
        return isPeak(nums, 0, nums.length - 1);
    }
    private static int isPeak (int[] nums, int start, int end) {
        int mid = start + (end - start) / 2;
        if ( mid == nums.length - 1 && nums[mid] > nums[mid - 1])
            return mid;
        else if (nums[mid - 1] < nums[mid] && nums[mid] <  nums[mid + 1])
            return isPeak(nums, mid + 1, end);
        else if (nums[mid - 1] > nums[mid] && nums[mid] > nums[mid + 1])
            return isPeak(nums, start, mid - 1);
        else return -1;
    }
  • 这种相邻元素比较的题目中, 特殊情况必须放在binarySearch的method里面, 因为mid的不断变化势必会掉入这种edge conditions
    public static int findPeakElementByBinarySearch(int[] nums) {
        if (nums.length == 1) return 0;
        return isPeak(nums, 0, nums.length - 1);
    }
    private static int isPeak (int[] nums, int start, int end) {
        int mid = start + (end - start) / 2;
        if ( mid == nums.length - 1 && nums[mid] > nums[mid - 1]
                || mid == 0 && nums[mid] > nums[mid + 1]
                || nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1])
            return mid;
        else if (nums[mid - 1] < nums[mid] && nums[mid] <  nums[mid + 1])
            return isPeak(nums, mid + 1, end);
        else if (nums[mid - 1] > nums[mid] && nums[mid] > nums[mid + 1])
            return isPeak(nums, start, mid - 1);
        else return -1;
    }

这个错犯的有点二, 第一个if的三个||相连条件里, 即便加上了start == end这个条件, 也不对. 因为一旦不符合peak, 又会掉落到第三个, 比较前面和后面的, 会出现溢出情况

  • 把特殊条件加上, 代码如下
    private static int isPeak (int[] nums, int start, int end) {
        int mid = start + (end - start) / 2;
        if (start == end) return start;
        else if (mid == start || mid == end) // end = start + 1
            return nums[start] < nums[end] ? end : start;
        else if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1])
            return mid;
        else if (nums[mid - 1] < nums[mid] && nums[mid] <  nums[mid + 1])
            return isPeak(nums, mid + 1, end);
        else if (nums[mid - 1] > nums[mid] && nums[mid] > nums[mid + 1])
            return isPeak(nums, start, mid - 1);
        else return -1;
    }

又出现了一个failed case {2, 1, 2} 并没被考虑到. 其实这种情况左右都是peak, 随便掉入递增递减都可以, 因此可以把最后一个else if变为else, 接收其他条件, 掉入到前面的peak中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值