다른 폴더에있는 모든 파일에서 100 개 번호를 찾을 수

존 :

나는 최근에 내가 질문 아래 질문을 받았다 인터뷰를했다 그리고 그것은 나에게 아주 쉽게 소리를하지만 마지막에 나를 위해 까다로운되었다.

모든 폴더와 그 하위 폴더에있는 파일이 많이 있습니다. 각 파일은 각 라인에 숫자를 많이해야합니다. 루트 폴더 감안할 때, 나는 모든 파일에서 100 대 번호를 찾을 필요가있다. 나는 아래의 해결책을했다 :

  • 라인으로 모든 파일 라인을 읽어보십시오.
  • 배열 목록의 각 수를 저장합니다.
  • 내림차순으로 정렬합니다.
  • 이제 목록에서 첫 번째 k 개의 번호를 얻을.

그러나 면접관이의 시간 복잡도가 될 것입니다 무엇을 나에게 물었다. 나는 우리가 그것을 정렬되기 때문에이 그래서 말했다 될거야 O (nlogn) 그리고 그는 우리가 프로그램보다 개선 할 수있는 방법을 물어? 당신은 메모리의 모든 내용을 저장하고 있기 때문에 다음 정렬 - 만약에 당신이 할 수없는 메모리에 맞게 모든 것을?

그때 나는 혼동하고이 문제를 아래 해결하기 위해 더 나은 / 효율적인 방법이 있다면 알아낼 수 없었다. 그는 효율적인 코드를 작성하는 나를 원했다. 이러한 목표를 달성 할 수있는 더 좋은 방법이 있나요?

아래는 내가 생각 해낸 내 원래의 코드는 다음과 같습니다

  private static final List<Integer> numbers = new ArrayList<>();

  public static void main(String[] args) {
    int k = 100;
    List<Integer> numbers = findKLargest("/home/david");

    // sort in descending order
    Collections.sort(numbers, Collections.reverseOrder());
    List<Integer> kLargest = new ArrayList<>();
    int j = 0;
    // now iterate all the numbers and get the first k numbers from the list
    for (Integer num : numbers) {
      j++;
      kLargest.add(num);
      if (j == k) {
        break;
      }
    }
    // print the first k numbers
    System.out.println(kLargest);
  }

  /**
   * Read all the numbers from all the files and load it in array list
   * @param rootDirectory
   * @return
   */
  private static List<Integer> findKLargest(String rootDirectory) {
    if (rootDirectory == null || rootDirectory.isEmpty()) {
      return new ArrayList<>();
    }

    File file = new File(rootDirectory);
    for (File entry : file.listFiles()) {
      if (entry.isDirectory()) {
        numbers.addAll(findKLargest(entry.getName()));
      } else {
        try (BufferedReader br = new BufferedReader(new FileReader(entry))) {
          String line;
          while ((line = br.readLine()) != null) {
            numbers.add(Integer.parseInt(line));
          }
        } catch (NumberFormatException | IOException e) {
          e.printStackTrace();
        }
      }
    }
    return numbers;
  }
MBO :

대신 모든 저장하는 N을 값 (전체 모든 파일에서 숫자 계산)하고 정렬 만 100 값을 저장할 수 있습니다 - 모든 순간에 가장 큰 것들.

이 작업을위한 편리하고 빠른 데이터 구조 - 우선 순위 큐 (보통에 따라 바이너리 힙 ). 생성 은 가기 힙보다 큰지마다 새로운 값 확인을 위해 그 후, 제 100 개 값을 -heap. 그렇다면 - 제거 탑, 새로운 항목을 삽입합니다.

공간의 복잡성은 O(K)시간 복잡도는, O(NlogK)여기, K=100그래서 복잡성으로 평가 될 수 O(1)O(N)(생략 일정 기간)

그것이 작동하는 방법 파이썬 예를 표시합니다 :

import heapq, random

pq = [random.randint(0, 20) for _ in range(5)]  #initial values
print(pq)
heapq.heapify(pq)                               #initial values ordered in heap
print(pq)
for i in range(5):
    r = random.randint(0, 20)    # add 5 more values
    if r > pq[0]:
        heapq.heappop(pq)
        heapq.heappush(pq, r)
    print(r, pq)

[17, 22, 10, 1, 15]   //initial values
[1, 15, 10, 22, 17]   //heapified, smallest is the left
29 [10, 15, 17, 22, 29]     //29 replaces 1
25 [15, 22, 17, 29, 25]     //25 replaces 10
14 [15, 22, 17, 29, 25]      //14 is too small
8 [15, 22, 17, 29, 25]       //8 is too small
21 [17, 21, 25, 29, 22]     //21 is in the club now

추천

출처http://43.154.161.224:23101/article/api/json?id=223909&siteId=1