zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Scrapy入门教程
    清华申请退学博士作品:完全用Linux工作
    Linux 计划任务 Crontab 笔记与总结(5)crontab 常见错误与案例
    《一个民企CEO的职场阳谋》–读书总结(下)
    《一个民企CEO的职场阳谋》–读书总结(上)
    《一个民企CEO的职场阳谋》–读书总结(上)
    CSDN开博一周年--总结、感想和未来规划
    《程序员,你伤不起》–读书笔记-序
    《程序员,你伤不起》–读书笔记-序
    3位同学简历中的14个问题
  • 原文地址:https://www.cnblogs.com/reynold-lei/p/3462399.html
Copyright © 2011-2022 走看看