2016 campus recruitment of baidu programming problem resolution software development


Related: LeetCode 60 - Permutation Sequence
http://codepub.cn/2015/09/29/2016-campus-recruitment-of-baidu-programming-problem-resolution-software-development/

康托展开
康托展开是一个全排列到一个自然数双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。


以下称第x个全排列是都是指由小到大的顺序。
X=a_n(n-1)!+a_{n-1}(n-2)!+\cdots+a_1\cdot0!
其中,a_i为整数,并且0\leq a_i<i,1\leq i\leq n
a_i的意义参见举例中的解释部分
例如,3 5 7 4 1 2 9 6 8 展开为 98884。因为X=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884.
解释:
排列的第一位是3,比3小的数有两个,以这样的数开始的排列有8!个,因此第一项为2*8!
排列的第二位是5,比5小的数有1、2、3、4,由于3已经出现,因此共有3个比5小的数,这样的排列有7!个,因此第二项为3*7!
以此类推,直至0*0!
显然,n位(0~n-1)全排列后,其康托展开唯一且最大约为n!,因此可以由更小的空间来储存这些排列。由公式可将X逆推出唯一的一个排列。
既然康托展开是一个双射,那么一定可以通过康托展开值求出原排列,即可以求出n的全排列中第x大排列。
如n=5,x=96时:
首先用96-1得到95,说明x之前有95个排列.(将此数本身减去!)
用95去除4! 得到3余23,说明有3个数比第1位小,所以第一位是4.
用23去除3! 得到3余5,说明有3个数比第2位小,所以是4,但是4已出现过,因此是5.
用5去除2!得到2余1,类似地,这一位是3.
用1去除1!得到1余0,这一位是2.
最后一位只能是1.
所以这个数是45321.

康托展开
例如:有一个数组S=["a","b","c","d"],它的其中之一个排列是S1=["b","c","d","a"],现在欲把S1映射成X,需要怎么做呢?按如下步骤走起
X=a43!+a32!+a21!+a10!

  1. 首先计算n,n等于数组S的长度,n=4
  2. 再来计算a4=”b”这个元素在数组["b","c","d","a"]中是第几大的元素。”a”是第0大的元素,”b”是第1大的元素,”c”是第2大的元素,”d”是第3大的元素,所以a4=1
  3. 同样a3=”c”这个元素在数组["c","d","a"]中是第几大的元素。”a”是第0大的元素,”c”是第1大的元素,”d”是第2大的元素,所以a3=1
  4. a2=”d”这个元素在数组["d","a"]中是第几大的元素。”a”是第0大的元素,”d”是第1大的元素,所以a2=1
  5. a1=”a”这个元素在数组["a"]中是第几大的元素。”a”是第0大的元素,所以a1=0
  6. 所以X(S1)=1\*3!+1\*2!+1\*1!+0\*0!=9
  7. 注意所有的计算都是按照从0开始的,如果[“a”,”b”,”c”,”d”]算为第1个的话,那么将X(S1)+1即为最后的结果
    static int charLength = 12;//定义字符序列的长度

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int n = scanner.nextInt();
            String lines[] = new String[n];
            int res[] = new int[n];//存储结果的数组
            for (int i = 0; i < n; i++) {
                lines[i] = scanner.next();
                res[i] = calculate(lines[i]);
            }
            for (int s : res) {
                System.out.println(s);
            }

        }
    }

    //计算某个字符序列的位次
    private static int calculate(String line) {
        Set<Character> s = new TreeSet<Character>();
        for (char c : line.toCharArray()) {
            s.add(c);
        }
        //存储每一个字符在该序列中是第几大的元素,然后将其值存储到counts数组中
        int counts[] = new int[s.size()];
        char[] chars = line.toCharArray();

        for (int i = 0; i < chars.length; i++) {
            Iterator<Character> iterator = s.iterator();
            int temp = 0;
            Character next;
            while (iterator.hasNext()) {
                next = iterator.next();
                if (next == chars[i]) {
                    counts[i] = temp;
                    s.remove(next);
                    break;
                } else {
                    temp++;
                }
            }
        }
        int sum = 1;
        for (int i = 0; i < counts.length; i++) {
            sum = sum + counts[i] * factorial(charLength - i - 1);
        }
        return sum;
    }

    //计算阶乘的函数
    private static int factorial(int n) {
        if (n > 1) {
            return n * factorial(n - 1);
        } else {
            return 1;
        }
    }
判断字符串是否出现
  1. 将字符串a存储在一个map集合中,以每个字符的ASCII码作为key,以其出现的次数作为value,记为aMap
  2. 遍历字符串b,对于b中的每一个字符,如果aMap的key中含有该字符的ASCII码,如果该key对应的value>1,那么将value值减1
  3. 否则value=1的话,那么将该键值对从aMap中移除
  4. 在判断aMap的key是否包含b中的某个字符的时候,只要有一次不包含,那么就说明没有都出现
  5. 否则的话,表示b中的字符在a中都出现过
    public static void main(String[] args) {
        //以某个字符的ASCII码作为key,以其出现的次数作为value
        Map<Integer, Integer> aMap = new HashMap<Integer, Integer>();

        Scanner input = new Scanner(System.in);
        while (input.hasNextLine()) {
            String a = input.nextLine();
            String b = input.nextLine();
            char[] chars = a.toCharArray();
            for (char c : chars) {
                if (aMap.keySet().contains((int) c)) {
                    int temp = aMap.get((int) c);
                    aMap.put((int) c, (temp + 1));
                } else {
                    aMap.put((int) c, 1);
                }
            }

            char[] chars1 = b.toCharArray();
            boolean flag = true;
            for (char c : chars1) {
                if (aMap.keySet().contains((int) c)) {
                    int temp = aMap.get((int) c);
                    if (temp == 1) {
                        //说明只有一个
                        aMap.remove((int) c);
                    } else {
                        //说明多过于一个
                        aMap.put((int) c, (temp - 1));
                    }

                } else {
                    flag = false;
                    break;
                }

            }

            if (flag) {
                System.out.println(1);
            } else {
                System.out.println(0);
            }
            aMap.clear();
        }
    }
组合概率
需要递推公式,然后用动态规划求解。
https://segmentfault.com/a/1190000005060870
以样例为例:
n = 2, a = 1, b = 3, x = 4,
则从[1, 3]中取出2个数的组合共有六对:
(1, 1), (1, 2), (1, 3),
(2, 2), (2, 3),
(3, 3)
其中,能组合成4,即相加为4的只有(1, 3), (2, 2)。
假设n=2, x=4的概率表示为rate(4, 2),其概率计算公式为
取两个数和为4概率 = 取一个数为1的概率取一个数为3的概率 + 取一个数为2的概率取一个数为2的概率 + 取一个数为3的概率*取一个数为1的概率
rate(4, 2) = rate(1, 1)*rate(3, 1) + rate(2,1)*rate(2,1) + rate(3,1)*rate(1,1)
可以进一步归纳为
rate(4,2) = rate(1,1)*rate((4-1),1) + rate(2,1)*rate(4-2,1) + rate(3,1)*rate((4-3),1)
我们现在将数字替换为字母
rate(x,n) = rate(1,n-1)*rate(x-1,n-1) + rate(2,n-1)*rate(x-2,n-1) + rate(3,n-1)*rate(x-3,n-1)
现在,我们将[1, 3]区间替换成字母[a,b],公式可以进一步归纳为
rate(x,n) = rate(a,1)*rate(x-a,n-1) + rate(a+1,1)*rate(x-(a+1),n-1) + ... + rate(b,1)*rate(x-b,n-1)
其中x-b>=a
至此,我们已可以确定,在区间[a,b]内取n个数其和为x的概率即为rate(x,n),这可以处理为一个递归函数,当n=1时,即可确定其值。
$区间下限 = a;
$区间上限 = b;
$区间数字个数 = $区间上限 - $区间下限 + 1;
function rate($x, $n) {
    // 当只取一个数时,其概率可以确定下来了
    if($n == 1) {
        if($x > $区间上限 || $x < $区间下限) {
            return 0;
        } else {
            return 1/$区间数字个数;
        }
    }

    $概率 = 0;
    for($i = $区间上限; $i < $区间下限; $i ++) {
        if($x-$i < $区间下限) break;

        $概率 += rate($i,1)*rate($x-$i, $n-1);
    }
    return $概率;
}
    static DecimalFormat dec = new DecimalFormat("0.0000");
    static double v[][];//表示取i个数时和为j的概率

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextInt()) {
            int n = input.nextInt();
            int a = input.nextInt();
            int b = input.nextInt();
            int x = input.nextInt();
            v = new double[n + 1][x + 1];
            double sum = b - a + 1;
            for (int i = a; i <= b; i++) {
                v[1][i] = 1.0 / sum;//取1个数和为i的概率
            }
            for (int i = 1; i <= n; i++) {//对n个数进行迭代
                for (int j = a; j <= b; j++) {//
                    for (int k = 1; k <= x; k++) {
                        if (k >= j) {
//                            print(v);
//                            System.out.println();
                            v[i][k] = v[i][k] + v[i - 1][k - j] / sum;
                        }
                    }
                }
            }
            //输出取n个数和为x的概率
            System.out.println(dec.format(v[n][x]));

        }
    }
    }


Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts