目录链接:
力扣编程题-解法汇总_分享+记录-CSDN博客
GitHub同步刷题项目:
https://github.com/September26/java-algorithms
原题链接:. - 力扣(LeetCode)
描述:
一个整数数组 original
可以转变成一个 双倍 数组 changed
,转变方式为将 original
中每个元素 值乘以 2 加入数组中,然后将所有元素 随机打乱 。
给你一个数组 changed
,如果 change
是 双倍 数组,那么请你返回 original
数组,否则请返回空数组。original
的元素可以以 任意 顺序返回。
示例 1:
输入:changed = [1,3,4,2,6,8] 输出:[1,3,4] 解释:一个可能的 original 数组为 [1,3,4] : - 将 1 乘以 2 ,得到 1 * 2 = 2 。 - 将 3 乘以 2 ,得到 3 * 2 = 6 。 - 将 4 乘以 2 ,得到 4 * 2 = 8 。 其他可能的原数组方案为 [4,3,1] 或者 [3,1,4] 。
示例 2:
输入:changed = [6,3,0,1] 输出:[] 解释:changed 不是一个双倍数组。
示例 3:
输入:changed = [1] 输出:[] 解释:changed 不是一个双倍数组。
提示:
1 <= changed.length <= 105
0 <= changed[i] <= 105
解题思路:
首先对原来的数组排序,排序不会影响最终的结果,但是从小到大选择可以避免重复被选中。
其次设置一个等长的数组useArray,记录某个位置的数字是否被使用。
最后使用双指针,指针index1记录原数组指向的数字,index2指向双倍数组中的数字。
遍历index1时,再循环内寻找值等于changed[index1]*2的index2位置,找不到index2++,找到也index2++,因为还有下一轮。
如果index1位置对应的值为1,说明被使用,则修改index1和index2的位置,此时index2= max(index1 + 1, index2);
代码:
class Solution {
public:
vector<int> findOriginalArray(vector<int> &changed)
{
sort(changed.begin(), changed.end());
vector<int> used(changed.size(), 0);
int index1 = 0;
int index2 = 1;
vector<int> out;
while (index1 < changed.size())
{
int num = changed[index1];
if (used[index1] == 1)
{
index1++;
index2 = max(index1 + 1, index2);
continue;
}
int num2 = num * 2;
int count = out.size();
while (index2 < changed.size())
{
if (changed[index2] == num2)
{
changed[index2] = 1;
used[index1] = 1;
used[index2] = 1;
out.push_back(num);
index2++;
break;
}
index2++;
}
if (count == out.size())
{
vector<int> out2(0);
return out2;
}
index1++;
}
return out;
}
};