LeetCode之1346. 检查整数及其两倍数是否存在

概要

题目来源链接:https://leetcode-cn.com/problems/check-if-n-and-its-double-exist/

难度:简单

类型:数组

题目

给你一个整数数组 arr,请你检查是否存在两个整数 N 和 M,满足 N 是 M 的两倍(即,N = 2 * M)。

更正式地,检查是否存在两个下标 i 和 j 满足:

  • i != j
  • 0 <= i, j < arr.length
  • arr[i] == 2 * arr[j]

示例

示例 1:

输入:arr = [10,2,5,3]
输出:true
解释:N = 10 是 M = 5 的两倍,即 10 = 2 * 5 。
示例 2:

输入:arr = [7,1,14,11]
输出:true
解释:N = 14 是 M = 7 的两倍,即 14 = 2 * 7 。
示例 3:

输入:arr = [3,1,7,11]
输出:false
解释:在该情况下不存在 N 和 M 满足 N = 2 * M 。
 

提示:

2 <= arr.length <= 500
-10^3 <= arr[i] <= 10^3

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-n-and-its-double-exist
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

第一种思路,利用哈希表,对0需要进行特殊处理,将数组中的每个数放入哈希表,再用2乘以数组中的每个数,然后拿去哈希表中进行判断,如果哈希表中存在该数则返回true,否则返回false。

第二种思路,暴力破解,双层循环判断。

第三种思路是利用双指针(思路来源于:https://leetcode-cn.com/problems/check-if-n-and-its-double-exist/solution/shuang-zhi-zhen-fa-yu-hashmapfa-by-handling/)。

首先将数组排序,之后遍历数组,数组中正数与负数找2倍数是要区分开的,具体为:

例如:-8 -4 -1 0 1 8 9

当前遍历到的元素是负数时,双指针l应该是最左侧,因为负数的双倍数需要以左边临界点为起始点,左端为负数的最小值,负数*2是会变小的。

  • 1:当前 arr[l] > arr[i]*2 则说明当前l指向元素已经大于元素的双倍数,需要跳出循环,因为已经找不到其对应的双倍数,数组元素从左至右依次变大。
  • 2:当前arr[l] < arr[i]*2 则说明l指向元素小,需要向右增大,因此执行 ++l
  • 3:若arr[l] =arr[i]*2 返回true

当前遍历到的元素是正数时,双指针r应该是最右侧,因为正数的双倍数需要以右边临界点为起始点,右端为正数的最小值,正数*2是会变大的。

  • 1:当前 arr[r] > arr[i]*2 则说明当前r指向元素已经大于元素的双倍数,需要--r,遍历较小的元素。
  • 2:当前arr[r] < arr[i]*2 则说明r指向元素小于遍历元素的二倍,向左移动已经不能满足,因此跳出循环。
  • 3:若arr[r] =arr[i]*2 返回true

代码

第一种思路:

    /**
     * 题目:1346. 检查整数及其两倍数是否存在(第一种算法:利用哈希表)
     * @param arr 数组
     * @return 如果存在返回true,否则返回false
     */
    public boolean checkIfExist(int[] arr) {
        Map map=new HashMap();
        int zeroCount=0;// 对0进行特殊处理
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==0){// 计算0的个数
                zeroCount++;
            }
            map.put(arr[i],0);
        }
        if(zeroCount>=2){// 如果存在两个以上的0,就输出true
            return true;
        }else {
            for (int i : arr) {
                if (i!=0&&map.containsKey(i * 2)) {
                    return true;
                }
            }
        }
        return false;
    }

第二种思路:

    /**
     * 题目:1346. 检查整数及其两倍数是否存在(第二种算法:暴力破解,循环判断)
     *
     * @param arr 数组
     * @return 如果存在返回true,否则返回false
     */
    public boolean checkIfExist(int[] arr){
        int zeroCount=0;
        for (int num : arr) {
            if(0==num){
                zeroCount++;
            }else {
                int temp=num*2;// 不能用除,而需要用乘法
                for (int j : arr) {
                    System.out.println(num);
                    if(temp!=0&&temp==j){
                        return true;
                    }
                }
            }
        }
        if(zeroCount>=2){
            return true;
        }
        return false;
    }

第三种思路:

    public boolean checkIfExist(int[] arr) {
        Arrays.sort(arr);
        for (int i = 0; i != arr.length; ++i) {
            if (arr[i] < 0) {
                int l = 0;
                while (i != l && arr[l] < 0) {

                    if (arr[l] < arr[i] * 2) ++l;
                    else if (arr[l] > arr[i] * 2) break;
                    else return true;
                }
            } else {
                int r = arr.length - 1;
                while (i != r) {
                    if (arr[r] > arr[i] * 2) --r;
                    else if (arr[r] < arr[i] * 2) break;
                    else return true;
                }
            }
        }
        return false;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值