透過給定操作將陣列縮減至最多一個元素


在這個問題中,我們將透過在每次輪換中執行給定的操作,將陣列的大小縮減為 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。在每次迭代中,我們將對陣列進行排序,並在排序陣列的前兩個元素上執行給定的操作。最後,我們將根據陣列的大小列印輸出。

演算法

步驟 1 - 將陣列的大小儲存在“len”變數中。

步驟 2 - 使用 while 迴圈開始遍歷陣列。

步驟 3 - 在迴圈中使用 sort() 方法以反向順序對陣列進行排序。

步驟 4 - 取陣列的第一和第二個元素。另外,取陣列的第一和第二個元素之間的差值。

步驟 5 - 如果差值為 0,則刪除陣列的第一個元素,並將“len”減少 2。如果差值不為 0,則刪除前兩個元素並將“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) 用於在優先順序佇列中儲存元素。

當我們需要在插入或刪除任何元素後以特定順序獲取陣列資料時,優先順序佇列資料結構始終很有用。它實現了堆資料結構,這使得插入和刪除變得。

更新於: 2023年7月22日

83 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.