zoukankan      html  css  js  c++  java
  • Leetcode: K-th Smallest in Lexicographical Order

    Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n.
    
    Note: 1 ≤ k ≤ n ≤ 109.
    
    Example:
    
    Input:
    n: 13   k: 2
    
    Output:
    10
    
    Explanation:
    The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so the second smallest number is 10.

    第二遍做法:参考https://discuss.leetcode.com/topic/64624/concise-easy-to-understand-java-5ms-solution-with-explaination

    Actually this is a denary tree (each node has 10 children). Find the kth element is to do a k steps preorder traverse of the tree.

    Initially, image you are at node 1 (variable: curr),
    the goal is move (k - 1) steps to the target node x. (substract steps from k after moving)
    when k is down to 0, curr will be finally at node x, there you get the result.

    we don't really need to do a exact k steps preorder traverse of the denary tree, the idea is to calculate the steps between curr and curr + 1 (neighbor nodes in same level), in order to skip some unnecessary moves.

    Main function
    Firstly, calculate how many steps curr need to move to curr + 1.

    1. if the steps <= k, we know we can move to curr + 1, and narrow down k to k - steps.

    2. else if the steps > k, that means the curr + 1 is actually behind the target node x in the preorder path, we can't jump to curr + 1. What we have to do is to move forward only 1 step (curr * 10 is always next preorder node) and repeat the iteration.

    calSteps function

      1. how to calculate the steps between curr and curr + 1?
        Here we come up a idea to calculate by level.
        Let n1 = curr, n2 = curr + 1.
        n2 is always the next right node beside n1's right most node (who shares the same ancestor "curr")
        (refer to the pic, 2 is right next to 1, 20 is right next to 19, 200 is right next to 199).

      2. so, if n2 <= n, what means n1's right most node exists, we can simply add the number of nodes from n1 to n2 to steps.

      3. else if n2 > n, what means n (the biggest node) is on the path between n1 to n2, add (n + 1 - n1) to steps.

      4. organize this flow to "steps += Math.min(n + 1, n2) - n1; n1 *= 10; n2 *= 10;"

     1 public class Solution {
     2     public int findKthNumber(int n, int k) {
     3         int curr = 1;
     4         k--;
     5         while (k > 0) {
     6             int steps = calc(n, curr, curr+1);
     7             if (k >= steps) {
     8                 k -= steps;
     9                 curr = curr + 1;
    10             }
    11             else {
    12                 k -= 1;
    13                 curr = curr * 10;
    14             }
    15         }
    16         return curr;
    17     }
    18     
    19     public int calc(int n, long n1, long n2) {
    20         int steps = 0;
    21         while (n1 <= n) {
    22             steps += Math.min(n+1, n2) - n1;
    23             n1 *= 10;
    24             n2 *= 10;
    25         }
    26         return steps;
    27     }
    28 }

    下面是我自己的方法,参考Lexicographical Numbers这道题,对是对的,但是挨个访问,没有skip, TLE了

     1 public class Solution {
     2     public int findKthNumber(int n, int k) {
     3         int cur = 1;
     4         for (int i=1; i<k; i++) {
     5             if (cur * 10 <= n) {
     6                 cur = cur * 10;
     7             }
     8             else {
     9                 while (cur>10 && cur%10==9) {
    10                     cur /= 10;
    11                 }
    12                 cur  = cur + 1;
    13             }
    14         }
    15         return cur;
    16     }
    17 }
  • 相关阅读:
    topcoder srm 681 div1
    topcoder srm 683 div1
    topcoder srm 684 div1
    topcoder srm 715 div1
    topcoder srm 685 div1
    topcoder srm 687 div1
    topcoder srm 688 div1
    topcoder srm 689 div1
    topcoder srm 686 div1
    topcoder srm 690 div1 -3
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/6143506.html
Copyright © 2011-2022 走看看