当前位置 博文首页 > Inmaturity_7的博客:算法练习贴--28--二倍数对数组(Java)
给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 “对于每个 0 <= i < len(A) / 2,都有 A[2 * i + 1] = 2 * A[2 * i]” 时,返回 true;否则,返回 false。
(题目来源:力扣(LeetCode))
示例 1:
输入:[3,1,3,6]
输出:false
示例 2:
输入:[2,1,2,6]
输出:false
示例 3:
输入:[4,-2,2,-4]
输出:true
解释:我们可以用 [-2,-4] 和 [2,4] 这两组组成 [-2,-4,2,4] 或是 [2,4,-2,-4]
示例 4:
输入:[1,2,4,16,8,4]
输出:false
提示:
0 <= A.length <= 30000
A.length 为偶数
-100000 <= A[i] <= 100000
1.排序计数
package com.lxf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CanReorderDoubled {
public static void main(String[] args) {
System.out.println(canReorderDoubled(new int[] {7,-15,-15,23,-3,80,-35,40,68,22,44,98,20,0,-34,8,40,41,16,46,16,49,-6,-11,35,-15,-74,72,-8,60,40,-2,0,-6,34,14,-16,-92,54,14,-68,82,-30,50,22,25,16,70,-1,-96,11,45,54,40,92,-35,29,80,46,-30,27,7,-70,-37,41,-46,-98,1,-33,-24,-86,-70,80,-43,98,-49,30,0,27,2,82,36,0,-48,3,-100,58,32,90,-22,-50,-12,36,6,-3,-66,72,8,49,-30}));
}
public static boolean canReorderDoubled(int[] A) {
public static boolean canReorderDoubled(int[] A) {
Arrays.sort(A);
Map<Integer, Integer> map=new HashMap<Integer, Integer>();
//统计0的个数,因为0不符合计算规则,需单独处理
int countZ=0;
for (int i = 0; i < A.length; i++) {
if(A[i]==0) {
countZ++;
}else{
//A[i]不为0时
//flag:判断当前值是奇数还是偶数
boolean flag=A[i]%2==0;
if(flag&&map.containsKey(A[i]>>1)&&map.get(A[i]>>1)>0) {
//如果为偶数,且它的一半值存在key中,且这个它的一半值key对应的数大于0
//则将它的一半值key对应的value--
map.put(A[i]>>1, map.get(A[i]>>1)-1);
}else if(map.containsKey(A[i]<<1)&&map.get(A[i]<<1)>0) {
//如果为奇数或偶数,且它的两倍存在key中,且这个两倍数key对应的数大于0
//将它的两倍数key对应的value--
map.put(A[i]<<1, map.get(A[i]<<1)-1);
}else {
//key中无两倍值key或一半值key
//将这个数存入map中
//第一次存入:初始值为1
//多次存入,则是key对应的值++
map.put(A[i],map.getOrDefault(A[i], 0)+1);
}
}
}
//判端0是否为偶数
if(countZ%2!=0) {
return false;
}
if(map.values().size()>0) {
//当map的有value,且value不等于0时,说明有些没有对应的半值或者二倍值
if(Collections.max(map.values())!=0) {
return false;
}
}
return true;
}
}
2.排序计数(官方题解,稍加修改)
class Solution {
public boolean canReorderDoubled(int[] A) {
//复制A数组到B数组中
Integer[] B = new Integer[A.length];
for (int i = 0; i < A.length; ++i)
B[i] = A[i];
//将数组取正并排序
Arrays.sort(B, Comparator.comparingInt(Math::abs));
//新建一个map存储数字以及它对应的次数
Map<Integer, Integer> count = new HashMap();
for (int x: B)
count.put(x, count.getOrDefault(x, 0) + 1);
//循环B数组
for (int x: B) {
//如果这个值没有了进入下一次循环
if (count.get(x) == 0) continue;
//如果这个值的两倍值没有,那么直接返回false
if (count.getOrDefault(2*x, 0) <= 0) return false;
//将这两个数减去次数
count.put(x, count.get(x) - 1);
count.put(2*x, count.get(2*x) - 1);