• Chp18: Hard


    18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators.

    Solution: deal with 759 + 674.

    1. add 759 + 674, but forget to carry. get 323

    2. add 759 + 674, but only do the carrying, rather than the addition of each digit. get 1110

    3. add the result of the first two operations(recursively): 1110 + 323 = 1433

    1 public int add(int a, int b){
    2     if(b == 0) return a;
    3     if(a == 0) return b;
    4     int sum = a ^ b; // 1
    5     int ope = (a & b) << 1; // 2
    6     return add(sum, ope);
    7 }

    18.3 Write a method to randomly generate a set of m integers from an array of size n. Each element must have equal probability of being chosen.

    Solution: shrink the array to no longer contain elements that already chosen.

     1 public int[] pickMRandomly(int[] original, int m){
     2     int[] result = new int[m];
     3     int array = original.clone(); // 必须要先复制出来,否则会更改原来数组的结构
     4     for(int j = 0; j < m; j ++){
     5         int index = random(j, array.length - 1);
     6         result[j] = array[index];
     7         array[index] = array[j];
     8     }
     9     return result;
    10 }

    18.6 Describe an algorithm to find the smallest one million numbers in one billion numbers. Assume that the computer memory can hold all one billion numbers.

     Selection Rank Algorithm: find the ith smallest (or largest) element in an array in linear time.

    If the elements are unique, can find it in O(n).

    1.pick a random element in the array and use it as a "pivot". Partition elements around the pivot, keep track of the number of elements on the left side of the partition.

    2.if there are exactly i elements on the left, then you just return the biggest element on the left.

    3.if the left side is bigger than i, repeat the algo on just the left part of the array.

    4.if the left side is smaller than i, repeat the algo on the right, but look for the lement with rank i - leftsize.

     1 public int partition(int[] array, int left, int right, int pivot){
     2     while(true){
     3         while(left <= right && array[left] <= pivot) left ++;
     4         while(left <= right && array[right] > pivot) right --;
     5         if(left > right) return left - 1;
     6         swap(array, left, right);
     7     }
     8 }
     9 public int rank(int[] array, int left, int right, int rank){
    10     int pivot = array[randomIntInRange(left, right)];
    11     int leftEnd = partition(array, left, right, pivot);
    12     int leftSize = leftEnd - left + 1;
    13     if(leftSize == rank + 1) return max(array, left, leftEnd);
    14     else if(rank < leftSize) return rank(array, left, leftEnd, rank);
    15     else return rank(array, leftEnd + 1, right, rank - leftSize);
    16 }
  • 相关阅读:
    IR的评价指标之MRR
    双击启动tomcat中的startup.bat闪退原因及解决方法
    裁判文书网采集说明
    Java 验证码识别之多线程打码兔
    JVM 内存分配机制总结
    Java中多态的一些简单理解
    Java Callable并发编程模板
    JVM
    Command
    解决PHP下载文件时因时文件太大而报404错误
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/3462399.html
Copyright © 2020-2023  润新知