2014-04-26 20 views
5

Cho số n và một mảng có kích thước m, trong đó m < n. Với điều kiện là mỗi số trong mảng nằm trong khoảng từ 0 đến n-1 (bao gồm), tôi muốn nhận được càng nhiều càng tốt danh sách các số n-m từ 0 đến n-1 không nằm trong mảng.Tạo danh sách các số còn lại

Đó là cách tôi đang làm nó (trong giả), nhưng nó cảm thấy khá hiệu quả và tôi tự hỏi nếu có một cách tốt hơn:

int[] remaining (int[] assigned) { 
    Set<int> s 
    int[n-m] remaining 
    add each int in assigned to s 
    for(i = 0 to n-1) 
     if(not s.contains(i)) remaining.add(i); 
} 

Đây không phải là bất kỳ ngôn ngữ máy tính cụ thể nhưng nó nên bất lịch sự. Chúng tôi giả định rằng việc truy cập vào một mảng là tất nhiên O (1) và thêm/kiểm tra một bộ là O (log (n)) như là một tập AVL sẽ được. Vì vậy, về cơ bản tôi đang cố gắng để có được điều này trong thời gian tuyến tính, thay vì O (n · logn) như bây giờ, nhưng nếu mảng ban đầu không được sắp xếp tôi không biết làm thế nào để đi về nó, hoặc nếu nó thậm chí có thể .

+1

Nếu bạn có khả năng nhớ, một mảng bit kích thước n có thể được sử dụng để giải quyết vấn đề trong thời gian tuyến tính. (Thuật toán là hiển nhiên.) – ooga

+0

Tôi không hoàn toàn theo thuật toán hiển nhiên. Bạn có thể giải thích? CHỈNH SỬA: Ồ, chờ chút, bạn có nghĩa là boolean? – Setzer22

+0

Ồ, xin lỗi! Tôi đã nghĩ rằng bạn sẽ init mảng bit cho tất cả 0, đi qua danh sách các số thiết lập bit tương ứng với 1, và sau đó đi qua mảng bit và in các vị trí của tất cả các bit vẫn bằng 0. – ooga

Trả lời

2

Tôi nghĩ rằng nó sẽ nhanh hơn một chút giả cũng

int[] remaining (int[] assigned) { 
    Set<int> s 
    int[n] all 
    int[n-m] remaining 
    for(i = 0 to m-1) 
     all[assigned[i]]=-1 
    int counter=0 
    for(i = 0 to n-1) 
     if (all[i]==-1) 
      remaining[counter]=all[i] 
      counter++ 
    return remaining 
} 
3

sao chép mảng vào một bản đồ băm H. Điều này mất O(m).

for i from 0 to n-1 
    if(H.ispresent(i) == FALSE) 
     output i 

Vòng lặp này mất O(n). Như n>=m tổng thể mức độ phức tạp là O(n)

+0

Hoặc bây giờ tôi nghĩ về nó, tôi có thể sử dụng một mảng các số nguyên (mà sẽ là một thực hiện cụ thể của một bản đồ băm với cặp khóa-giá trị là int-int. Dù sao, câu trả lời hay, cảm ơn! – Setzer22

+0

@ Setzer22 (về bản chất) với ý tưởng mảng bit, ngoại trừ việc sử dụng ints (hoặc một hashmap) sẽ chiếm nhiều không gian hơn. – ooga

2

Các bitset (bit mảng) ý tưởng:

#include <iostream> 
#include <fstream> 
#include <bitset> 

const int SIZE = 10; // for example 

int main() { 
    std::bitset<SIZE> bs; 
    int i; 

    std::ifstream fin("numbers.txt"); 
    while (fin >> i) 
     bs.set(i); 
    fin.close(); 

    for (i = 0; i < SIZE; ++i) 
     if (!bs[i]) 
      std::cout << i << '\n'; 

    return 0; 
} 
+0

Tôi thực sự đang sử dụng Java để không may mắn với STL, nhưng tôi đã hỏi ý tưởng chung và trả lời nó, vì vậy cảm ơn !.Và mặc dù điều này về cơ bản giống như khái niệm bitet mang một chi phí xấu với nó như bộ nhớ của bất kỳ máy tính hiện đại nào phải được viết ít nhất là byte trên byte, vì vậy không có phép truy cập bit, nó chỉ hoạt động bitwise bên dưới nó, mà hầu hết mọi người không thích. – Setzer22

+0

@ Setzer22 Đó là sự cân bằng, được rồi. Tôi cho rằng bạn có, có khả năng, hàng triệu (hoặc hàng tỷ) con số, nếu không thì tại sao phải bận tâm với việc tối ưu hóa? Vì vậy, sử dụng bộ nhớ sẽ là quan trọng, IMHO. – ooga

1

Nếu bạn phải tìm 1 hoặc 2 số bị thiếu, bạn luôn có thể sử dụng tổng và/hoặc sản phẩm của các số để tìm ra các số bị thiếu. Nếu số lớn hơn 2

Mã để sử dụng Bitset trong java để tìm số bị thiếu.

public List<Integer> findMissingNumbers(List<Integer> input,int maxNum){ 

/* Bạn cũng có thể liên lạc qua danh sách và tìm maNum sau. Các bitet dựa trên vector và có thể tăng kích thước */ nếu (input == null || input.size() == 0) trả về null;

BitSet existSet=new BitSet(maxNum); 
for(int val:input){ 
    existSet.set(val); 
} 

List<Integer> missingNum=new ArrayList<Integer>(); 
for(int i=0;i<existSet.length()){ 
    nextIndex=bitSet.nextClearBit(); 
    if(nextIndex==-1) 
     break; 
    missingNum.add(nextIndex); 
    index=nextIndex+1; 

} 
return missingNum; 

}

Các vấn đề liên quan