2014-04-26 4 views
5

주어진 숫자 n 및 크기가 m 인 배열은 m < n입니다. 배열의 각 숫자가 0과 n-1 (포함) 사이에 있으면 배열에없는 0에서 n-1까지의 n-m 숫자 목록을 최대한 효율적으로 가져 오려고합니다.나머지 숫자 목록 생성

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); 
} 

이 특정 컴퓨터 언어가 아니라 그것을해야한다 : 나는 (의사 코드)를하고 있어요,하지만 오히려 비효율적 인 느낌과 더 나은 방법이 있는지 궁금 해요 방법

낫다. 우리는 배열에 접근하는 것은 당연히 O (1)이고, AVL 세트가 될 때 세트를 추가/체크하는 것은 O (log (n))라고 가정합니다. 그래서 기본적으로 지금처럼 O (n • logn) 대신에 선형 시간에 이것을 얻으려고합니다.하지만 초기 배열이 정렬되어 있지 않다면 어떻게 할 것인지, 아니면 가능할 지 모르겠습니다. .

+1

크기 n의 비트의 배열은 선형 시간의 문제를 해결하기 위해 사용될 수있다. (알고리즘은 분명합니다.) – ooga

+0

나는 명백한 알고리즘을 따르지 않습니다. 설명해 주시겠습니까? 편집 : 오, 잠깐, 당신은 부울을 의미합니까? – Setzer22

+0

오, 미안 해요! 나는 비트 배열을 모두 0으로 초기화하고, 해당 비트를 1로 설정하는 숫자 목록을 살펴본 다음 비트 배열을 통과하고 여전히 0 인 모든 비트의 위치를 ​​인쇄한다고 생각했습니다. – ooga

답변

2

내가 조금 더 빨리 의사 찾을해야하는 경우도

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

배열을 해시맵 H에 복사하십시오. 이 작업에는 O(m)이 필요합니다.

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

for 루프는 O(n)입니다. n>=m으로 전체 복잡성은 O(n)

+0

또는 이제는 정수 배열을 사용할 수 있습니다 (키 - 값 쌍이 int-int 인 해시 맵의 특정 구현이 될 수 있습니다.) 어쨌든 좋은 대답입니다. 감사합니다. – Setzer22

+0

@ Setzer22 동일 할 것입니다. int (또는 hashmap)을 사용하는 것이 훨씬 더 많은 공간을 차지한다는 것을 제외하고 비트 배열 아이디어에 (사실상). – ooga

2

비트 세트 (비트 배열) 아이디어 :

#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

글쎄, 나는 실제로 자바를 사용하므로 STL과 아무런 행운이 없다. 그러나 나는 일반적인 생각을 요구했다. 대답 해 주셔서 감사합니다.그리고 이것이 근본적으로 동일하더라도 비트 셋 개념은 현대 컴퓨터의 메모리가 바이트 당 최소한 바이트로 작성되어야하므로 추악한 오버 헤드가 발생합니다. 따라서 매직 비트 액세스가 없으므로 비트 연산만으로 대부분의 사람들이 싫어해. – Setzer22

+0

@ Setzer22 그건 절충점입니다. 좋습니다. 잠재적으로 수백만 (또는 수십억) 개의 숫자가 있다고 가정 했었습니다. 그렇지 않은 경우 왜 최적화가 필요합니까? 따라서 메모리 사용이 중요 할 것입니다. – ooga

1

있을 거라고 생각 1 또는 2 개의 누락 된 숫자가 있으면 누락 된 숫자를 계산할 때 숫자의 합 및/또는 곱을 항상 사용할 수 있습니다 .2 이상인 경우

Java에서 Bitset을 사용하여 누락 된 번호를 찾는 코드입니다.

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

/* 또한 목록을 검토하고 나중에 maNum을 찾을 수도 있습니다. 비트 집합은 벡터를 기반으로하므로 크기가 커질 수 있습니다. */ if (input == null || input.size() == 0) return 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; 

}