• [LintCode] Nuts & Bolts Problem


    Given a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping between nuts and bolts. Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means nut can only be compared with bolt and bolt can only be compared with nut to see which one is bigger/smaller.

    We will give you a compare function to compare nut with bolt.

    Example

    Given nuts = ['ab','bc','dd','gg'], bolts = ['AB','GG', 'DD', 'BC'].

    Your code should find the matching bolts and nuts.

    one of the possible return:

    nuts = ['ab','bc','dd','gg'], bolts = ['AB','BC','DD','GG'].

    we will tell you the match compare function. If we give you another compare function.

    the possible return is the following:

    nuts = ['ab','bc','dd','gg'], bolts = ['BC','AA','DD','GG'].

    So you must use the compare function that we give to do the sorting.

    The order of the nuts or bolts does not matter. You just need to find the matching bolt for each nut.

    Solution 1. O(n) runtime, O(n) space, assuming the nut to bolt mapping is a simple String comparison.

    1. create a hashmap from each nut to its index;

    2.  iterate through all bolts and check if each bolt exists in the hashmap. If it does, simply sets nuts[i] to bolt[i].

    This is a solution for a simplified version of this problem. If we are guranteed of a 1 to 1 mapping and this mapping is simply a

    string match, then we can simply copy one array to the other array.

    To the original problem which only provides us an abstract compare method. The mapping relation is hid from us, so we can't 

    make any assumptions about this mapping in our algorithm.

    Solution 2. O(n*logn) runtime

    The goal is to sort both nuts and bolts arrays so they match at all indices. The simpliest way is sort both arrays separately. But this 

    approach is not viable since comparison inside one array is forbidden. 

    Comparison between nut and bolt is allowed and there is a one to one mapping between nut and bolt. So we can use quick sort 

    to sort both arrays at the same time.

    1.  pick the first bolt bolt[0] as pivot value to partition the array of nuts, return the index of nut which maps to bolt[0];

       This nut is already in its sorted position based on pivot bolt[0];

    2.  use the returned nut index pivotIdx to get nuts[pivotIdx] as pivot to partition the array of bolts;

       bolts[pivotIdx] will be in its sorted position after partition. 

    3.   repeat the above partition for both the left and right partition of nuts and bolts arrays until all nuts and bolts are matched.

     1 /**
     2  * public class NBCompare {
     3  *     public int cmp(String a, String b);
     4  * }
     5  * You can use compare.cmp(a, b) to compare nuts "a" and bolts "b",
     6  * if "a" is bigger than "b", it will return 1, else if they are equal,
     7  * it will return 0, else if "a" is smaller than "b", it will return -1.
     8  * When "a" is not a nut or "b" is not a bolt, it will return 2, which is not valid.
     9 */
    10 public class Solution {
    11     public void sortNutsAndBolts(String[] nuts, String[] bolts, NBComparator compare) {
    12         if(nuts == null || nuts.length == 0 || bolts == null || bolts.length == 0) {
    13             return;
    14         }
    15         quickSortRecur(nuts,  bolts, 0, nuts.length - 1, compare);
    16     }
    17     private void quickSortRecur(String[] nuts, String[] bolts, int start, int end, NBComparator compare) {
    18         if(start < end) {
    19             //choose the first bolt as pivot to partition nuts
    20             int pivot = partition(nuts, start, end, bolts[start], compare);
    21             //use the nut of position pivot as pivot to partition bolts
    22             partition(bolts, start, end, nuts[pivot], compare);
    23             
    24             quickSortRecur(nuts, bolts, start, pivot - 1, compare);
    25             quickSortRecur(nuts, bolts, pivot + 1, end, compare);
    26         }
    27     }
    28     private int partition(String[] str, int start, int end, String pivot, NBComparator compare) {
    29         //swap the first element with the element that is equal to pivot
    30         for(int i = start; i <= end; i++) {
    31             if(compare.cmp(str[i], pivot) == 0 || compare.cmp(pivot, str[i]) == 0) {
    32                 swap(str, i, start);
    33                 break;
    34             }
    35         }
    36         //use the newly swapped element as pivot(the same string with the parameter pivot)
    37         //to partition str
    38         int i = start + 1; 
    39         for(int j = start + 1; j <= end; j++) {
    40             if(compare.cmp(str[j], pivot) == -1 || compare.cmp(pivot, str[j]) == 1) {
    41                 swap(str, i, j);
    42                 i++;
    43             }
    44         }
    45         //final swap to put element of value pivot into its sorted position
    46         swap(str, start, i - 1);
    47         return i - 1;
    48     }
    49     private void swap(String[] str, int idx1, int idx2) {
    50         String temp = str[idx1];
    51         str[idx1] = str[idx2];
    52         str[idx2] = temp;
    53     }
    54 };

    Related Problems

    Sort Integers II

  • 相关阅读:
    MVC架构模式
    Promise对象
    Trick:如何去掉html标签点击时的蓝色边框
    动态REM
    Ajax 详解及CORS
    数据预测之BP神经网络具体应用以及matlab代码
    Pearson相关系数
    Java linux lame .wav音频转mp3 并且压缩
    JavaWeb向浏览器返回一个音频流
    Tomcat 运行 idea 编译好的 .class JavaWeb 项目
  • 原文地址:https://www.cnblogs.com/lz87/p/7524336.html
Copyright © 2020-2023  润新知