题目描述:
给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 “对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 * arr[2 * i]” 时,返回 true;否则,返回 false。
示例 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]
示例 4:
输入:arr = [1,2,4,16,8,4]
输出:false
提示:
0 <= arr.length <= 3 * 104
arr.length 是偶数
-105 <= arr[i] <= 105
方法1:
主要思路:解题链接汇总
(1)升序排序+哈希;
(2)然后遍历排序后的数组,根据当前数字是否是负数,决定下一个值是乘以2还是除以2获得的值;
class Solution {
public:
bool canReorderDoubled(vector<int>& arr) {
sort(arr.begin(),arr.end());
unordered_map<int,int> mp;
for(int i=0;i<arr.size();i++){
++mp[arr[i]];
}
for(int i=0;i<arr.size();++i){
if(mp[arr[i]]>0){
--mp[arr[i]];
if(arr[i]<0&&arr[i]%2==-1){
//负数,下一个值要除以2,但当前这个负数值是奇数,故直接返回false
return false;
}
int next_v=arr[i]>0?arr[i]*2:arr[i]/2;
if(mp[next_v]<=0){
return false;
}
--mp[next_v];
}
}
return true;
}
};
方法2:
主要思路:
(1)排序的规则按照绝对值大小进行升序排序;
class Solution {
public:
bool canReorderDoubled(vector<int>& arr) {
sort(arr.begin(),arr.end(),[](int&lhs,int&rhs){
return abs(lhs)<abs(rhs);
});
unordered_map<int,int> mp;
for(int i=0;i<arr.size();i++){
++mp[arr[i]];
}
for(int i=0;i<arr.size();++i){
if(mp[arr[i]]>0){
--mp[arr[i]];
if(mp[arr[i]*2]<=0){
return false;
}
--mp[arr[i]*2];
}
}
return true;
}
};
方法3:
主要思路:
(1)使用go实现;
type IntSlice []int
func (arr IntSlice)Len()int{
return len(arr)
}
func (arr IntSlice)Swap(i,j int){
arr[i],arr[j]=arr[j],arr[i]
}
func (arr IntSlice)Less(i,j int)bool{
lhs :=arr[i]
rhs :=arr[j]
if lhs<0 {
lhs = -lhs
}
if rhs<0 {
rhs = -rhs
}
return lhs<rhs
}
func canReorderDoubled(A []int) bool {
sort.Sort(IntSlice(A))
dict := map[int] int{
}
for _, n := range(A){
dict[n]++
}
for _, n := range(A){
if dict[n] > 0{
dict[n]--
if dict[n*2] <= 0{
return false
}
dict[n*2]--
}
}
return true
}