You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++:不排序去除vector重复值,解决缺失正整数代码失效问题

Hey there! I totally get your frustration—duplicates in your vector are breaking your FirstMissingPositive function, and you can't sort the array because your logic relies on the original order. Let's fix this with an efficient solution that sticks to your constraints: O(N) worst-case time and O(N) worst-case space (excluding input storage).

The Core Idea: Use a Hash Set for O(1) Duplicate Checks

Since we can't sort, the fastest way to track duplicates is with an unordered set (C++'s unordered_set), which gives average O(1) insertions and lookups (worst-case O(N), but overall still fits your time requirement). This lets us filter out duplicates without altering the original vector's order.

Solution 1: Extract Unique Positives First, Then Find the Missing One

This approach first collects all unique positive integers from the vector, then checks sequentially from 1 upwards to find the first missing value. It's straightforward and preserves the original array entirely:

#include <vector>
#include <unordered_set>

int FirstMissingPositive(std::vector<int>& nums) {
    std::unordered_set<int> unique_positives;
    int max_pos = 0;

    // Step 1: Gather all unique positive numbers and track the largest one
    for (int num : nums) {
        if (num > 0) {
            unique_positives.insert(num);
            if (num > max_pos) {
                max_pos = num;
            }
        }
    }

    // Step 2: Check from 1 to max_pos for the first missing positive
    for (int i = 1; i <= max_pos; ++i) {
        if (unique_positives.find(i) == unique_positives.end()) {
            return i;
        }
    }

    // If all numbers from 1 to max_pos exist, return the next integer
    return max_pos + 1;
}

Solution 2: Integrate Duplicate Checks Into Your Existing Logic

If you need to keep your original processing flow (e.g., you're doing in-place swaps like the classic first missing positive algorithm), you can use a set to track already processed values and skip duplicates to avoid infinite loops or incorrect state:

#include <vector>
#include <unordered_set>

int FirstMissingPositive(std::vector<int>& nums) {
    std::unordered_set<int> processed;
    int n = nums.size();

    for (int i = 0; i < n; ++i) {
        int current = nums[i];
        // Skip non-positives, out-of-range values, or duplicates we've already handled
        if (current <= 0 || current > n || processed.count(current)) {
            continue;
        }

        processed.insert(current);
        // Your original in-place swap logic (adjust if your code differs)
        while (current > 0 && current <= n && nums[current - 1] != current) {
            std::swap(nums[i], nums[current - 1]);
            current = nums[i]; // Update current after swap
            // Break early if we hit a duplicate we've already processed
            if (processed.count(current)) {
                break;
            }
            processed.insert(current);
        }
    }

    // Find the first position where the value doesn't match the index + 1
    for (int i = 0; i < n; ++i) {
        if (nums[i] != i + 1) {
            return i + 1;
        }
    }

    return n + 1;
}

Why This Works

  • Time Complexity: Each element is processed at most twice (once in the initial loop, once in the swap loop), so overall O(N). Set operations are average O(1), worst-case O(N) but still keeps the total time linear.
  • Space Complexity: The set stores up to N unique positive integers, so O(N) space, which meets your requirement.
  • Order Preservation: Neither solution sorts the original vector, so your order-dependent logic remains intact.

内容的提问来源于stack exchange,提问作者arcoxia tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:16:21