954.二倍数对数组——2022/4/1

1、题目

给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 “对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 * arr[2 * i]” 时,返回 true;否则,返回 false。

2、示例

示例 1

输入:arr = [3,1,3,6]
输出:false

示例 2

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

示例 3

输入:arr = [4,-2,2,-4]
输出:true
解释:可以用 [-2,-4] 和 [2,4] 这两组组成 [-2,-4,2,4] 或是 [2,4,-2,-4]

3、初步解答

3.1 思路及具体步骤

  • 首先需要将数组排序并按照数的种类分类
  • 00是二倍数对,所以如果有 0,则 0 的个数必须是偶数,否则返回false
  • 遍历分好类的数组,将使用完的数记录下来
  • 比较是否所有的数都被使用,使用完就返回true,否则返回false

3.2 代码

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,1,-8,8,-4,4,-4,2,-2,3,6,0,0,-3,-6,-6,-12};
        boolean a = canReorderDoubled(arr);
        System.out.println(a);
    }


    public static boolean canReorderDoubled(int[] arr) {
        Integer[][] num = new Integer[arr.length][2];
        Arrays.sort(arr);//排序数组
        int n = 0;//记录不同数的个数
        num[n][0] = arr[0];
        int zero = 0;//记录0的个数
        for (int i = 0; i < arr.length; i++) {
            num[i][1] = 0;
        }
        for (int i = 0; i < arr.length; i++) {
            if(num[n][0] == arr[i]){
                num[n][1]++;
            }else{
                num[++n][0] = arr[i];
                num[n][1] ++;
            }
            if(arr[i] == 0){
                zero++;
            }
        }
        if(zero % 2 != 0){//如果0的个数为奇数,则直接返回false
            return false;
        }
        /*
        由于上一个条件已经确定0是二倍数对数组的一个,所以判断是否有0,若有0则直接存在一个对数组
        这时用zero来记录二倍数对数组的个数
         */
        zero = zero > 0 ? 1 : 0;
        
        for (int i = 0; i < n + 1 ; i++) {//循环遍历所有数
            if(num[i][0] != 0){//0不考虑(前面已经判断过0的个数)
                for (int j = 0; j < n + 1; j++) {
                    if(num[j][0] != 0){//同样排除0
                        if((int)num[j][0] == 2 * num[i][0] && num[i][1] > 0){
                            if(num[j][1] >= num[i][1]){//根据个数判断哪个数被使用完
                                num[j][1] -= num[i][1];
                                num[i][1] = 0;
                                num[i][0] = 0;//由于循环中不考虑0,所以把已经使用完的数置零
                                zero++;//记录所有使用完的数的个数
                                if(num[j][1] == 0){
                                    num[j][0] = 0;
                                    zero++;
                                }
                            }else{
                                num[i][1] -= num[j][1];
                                num[j][1] = 0;
                                num[j][0] = 0;
                                zero++;
                                if(num[i][1] == 0){
                                    num[i][0] = 0;
                                    zero++;
                                }
                            }
                            break;
                        }
                    }

                }
            }
        }
        if(zero == n+1){//如果使用种数与数组中数的种数相同,则返回true
            return true;
        }else {
            return false;
        }
    }
}

执行用时:32 ms, 在所有 Java 提交中击败了81.96%的用户
内存消耗:48.7 MB, 在所有 Java 提交中击败了30.92%的用户

posted @   曦月宇望  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示