简体   繁体   中英

how can i amend this code to have a time complexity of o(log n) or o(n) instead of o(n^2)

How can I solve this in o(n) or o(logn)?

After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that the i-th group consists of si friends (1 ≤ si ≤ 4), and they want to go to Polycarpus together. They decided to get there by taxi. Each car can carry at most four passengers. What minimum number of cars will the children need if all members of each group should ride in the same taxi (but one taxi can take more than one group)? Following is my approach but in o(n^2)

import java.util.*;

public class taxi {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while (sc.hasNext()) {
      int cars = 0;
      int groups = sc.nextInt();
      int[] a = new int[groups];
      for (int i = 0; i < a.length; i++) {
        a[i] = sc.nextInt();
      }
      Arrays.sort(a);
      for (int i = a.length - 1; i > 0; i--) {

        if (a[i] == 4) {
          cars = cars + 1;
        } else {
          if (a[i] == 0) {
            break;
          } else {
            int y = 4 - a[i];
            for (int j = i - 1; j >= 0; j--) {
              if (y - a[j] == 0) {
                a[j] = 0;
                break;
              }
              if (y - a[j] > 0) {
                y = y - a[j];
                a[j] = 0;
              }
            }
            cars = cars + 1;
            Arrays.sort(a);
          }
        }
      }
      if (a[0] != 0) {
        cars++;
      }
      System.out.println(cars);
      cars = 0;
    }
  }
}

You'll never achieve O(log N) since you have to examine every group.

You can do it in a single traversal of the set of groups and a cache: so O(N).

For each group, count the size.

  1. If it's 4, then add a taxi.
  2. If it's 3, then attempt to pair with a cached 1, if not, cache that group.
  3. If it's 1, then attempt to pair with a cached 3, if not, cache that group.
  4. If it's 2, then attempt to pair with a cached 2, if not, cache that group.

Examine your cache. Pair any group of 2 with one or more group of 1. Then pair any remaining groups of 1.

A similar solution to what Bathsheba suggested, but based on the number of groups of each size instead of caching :

Iterate over the list of group once and count how many there are of each size. This required O(n) time and gives you the following counters :

int size1 = ...
int size2 = ...
int size3 = ...
int size4 = ...

Now calculate the number of cars based on these counters (this calculation takes O(1) ) :

int carsCount = size4; // add full cars (groups of 4)
carsCount += size3; // each group of 3 requires a separate car
carsCount += size2/2; // pairs of groups of 2
size1 -= size3; // group as many groups of 1 with groups of 3 as possible
boolean odd2s = (size2 % 2) == 1;
if (odd2s) {
    carsCount++; // add a car for the odd group of 2
}
if (size1 > 0) {
    if (odd2s) {
        size1 -= 2; // two groups of 1 can be paired with the odd group of 2
    }
}
if (size1 > 0) {
    carsCount += (size1 + 3) / 4; // any remaining groups of 1 are grouped in groups of 4
}

There are only 4 group sizes: 1, 2, 3 or 4.

Initialize an array of counts for each size, pass through your array of group sizes, incrementing the appropriate array element for the group size.

// Count the number of groups of each size.
int[] counts = new int[5];  // 1 more, just to use 1-based indexing.
for (int e : a) {
  ++counts[e];
}

which is O(n) .

Then, pass through like this:

int numTaxis =   counts[4];      // 1 taxi for each 4-sized group.
               + counts[3];      // 1 taxi for each 3-sized group.
               + counts[2] / 2;  // 1 taxi for each pair of 2-sized groups.

// But you can put a 1-sized group in each 3-sized group's taxi.
int unmatched1s = Math.max(0, counts[1] - counts[3]);

// You require ceil(unmatched1s / 4) taxis for the 1-sized groups -
// - but increase by 1 to handle the possibility of unpaired 2-sized group.
numTaxis += (unmatched1s + counts[2] % 2 + 3) / 4;

which is O(1) , meaning O(n) overall.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM