C++ 通过给定的操作将数组缩减为最多一个元素
在这个问题中,我们将通过每一轮执行给定的操作来将数组的大小减小为1或0。
我们可以在每一轮中对数组进行排序,以获得每一次迭代中的最大元素。同时,我们还可以使用头部数据结构来提高代码的性能。
问题陈述 −我们给定一个nums[]数组。我们需要通过执行以下操作来缩小数组的大小。
- 选择数组中的两个最大元素。
-
如果两个元素相同,则从数组中删除这两个元素。
-
如果两个元素不相同,则从数组中删除这两个元素,并将abs(第一个元素-第二个元素)插入数组中。
打印数组的最后一个元素。如果数组为空,则打印0。
示例
输入
nums = {5, 9, 8, 3, 2, 5};
输出
0
解释
- 在第一轮中,我们取9和8,并将它们的差添加到数组中。因此,数组变为[5,3,2,5,1]。
-
在第二轮中,我们取5和5。因此,数组变为[3,2,1]。
-
在下一轮中,我们取3和2。因此,数组变为[1,1]。
-
在最后一轮中,我们取1和1。因此,数组变为空,并且我们打印0。
输入
nums = {5, 5, 5, 5, 5};
输出
5
解释 - 我们两次删除一对5,数组中只剩下一个5。
输入
nums = {4, 8, 7, 6};
输出
1
解释 – 首先,我们选择8和7。所以,数组变成[4, 1, 6]。然后,我们选择4和6。所以,数组变成[1, 2]。在最后一次操作中,数组变成[1]。
方法1
在这种方法中,我们将遍历数组,直到数组的大小变为1或0。在每次迭代中,我们将对数组进行排序,并对排序后数组的前2个元素执行给定的操作。最后,我们将根据数组的大小打印输出。
步骤
步骤 1 - 将数组的大小存储在变量’len’中。
步骤 2 - 使用while循环遍历数组。
步骤 3 - 在循环中使用sort()方法以逆序对数组进行排序。
步骤 4 - 取数组的第一个和第二个元素。另外,取数组的第一个和第二个元素的差。
步骤 5 - 如果差值为0,则删除数组的第一个元素,并将’len’减2。如果差值不为0,则删除前2个元素,并将’len’减1。
步骤 6 - 最后,如果数组的大小为0,则返回0。否则,返回数组的第一个元素。
示例
#include <bits/stdc++.h>
using namespace std;
int findLast(vector<int> &nums) {
int len = nums.size();
int p = 0;
while (len > 1) {
// Sort array in reverse order
sort(nums.begin(), nums.end(), greater<int>());
// Take the first and second elements of the array
int a = nums[0];
int b = nums[1];
// Take the difference between the first and second element
int diff = a - b;
if (diff == 0) {
nums.erase(nums.begin());
nums.erase(nums.begin());
len -= 2;
} else {
nums.erase(nums.begin());
nums.erase(nums.begin());
nums.push_back(diff);
len -= 1;
}
}
// When the size of the array is 0
if (nums.size() == 0)
return 0;
return nums[0];
}
int main() {
vector<int> nums = {5, 9, 8, 3, 2, 5};
cout << "The last remaining element after performing the given operations is " << findLast(nums) << "\n";
return 0;
}
输出
The last remaining element after performing the given operations is 0
时间复杂度 – O(N*NlogN),其中O(N)用于遍历数组,O(NlogN)用于在每次迭代中对数组进行排序。
空间复杂度 – O(N)用于排序数组。
方法2
在这种方法中,我们将使用优先队列,该队列实现了堆数据结构。它始终以有序方式存储元素。因此,我们可以轻松地删除前两个最大的元素。
步骤
步骤1 - 定义名为’p_queue’的优先队列。
步骤2 - 将所有数组元素插入优先队列。
步骤3 - 循环直到优先队列的大小大于1。
步骤4 - 逐个移除优先队列的前两个元素。
步骤5 - 取两个元素的差值。
步骤6 - 如果差值不为0,则将其推入优先队列。
步骤7 - 最后,如果队列大小为0,返回0。
步骤8 - 否则,返回队列顶部的元素。
示例
#include <bits/stdc++.h>
using namespace std;
int findLast(vector<int> &nums) {
// Defining a priority queue
priority_queue<int> p_queue;
// Inserting array elements in priority queue
for (int p = 0; p < nums.size(); ++p)
p_queue.push(nums[p]);
// Make iterations
while (p_queue.size() > 1) {
// Take the first element from queue
int first = p_queue.top();
p_queue.pop();
// Get the second element from queue
int second = p_queue.top();
p_queue.pop();
// Take the difference of first and second elements
int diff = first - second;
if (diff != 0)
p_queue.push(diff);
}
// When queue is empty
if (p_queue.size() == 0)
return 0;
// Return the last remaining element
return p_queue.top();
}
int main() {
vector<int> nums = {5, 9, 8, 3, 2, 5};
cout << "The last remaining element after performing the given operations is " << findLast(nums) << "\n";
return 0;
}
输出
The last remaining element after performing the given operations is 0
时间复杂度-插入和删除元素的优先队列操作的时间复杂度为O(NlogN)。
空间复杂度-存储元素的优先队列的空间复杂度为O(N)。
当我们在插入或删除元素后需要按特定顺序获取数组数据时,优先队列数据结构总是有用的。它实现了堆数据结构,使得插入和删除变得更加高效。