LeetCode 樹

樹的代碼


// Definition for a binary tree node.
  public class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode(int x) { val = x; }
  }
 

101. Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3
But the following [1,2,2,null,3,null,3] is not:
    1
   / \
  2   2
   \   \
   3    3

代碼一 自己寫的 5%

public boolean isSymmetric(TreeNode root) {
    if (root == null) return true;
    TreeNode t1;
    TreeNode t2;
    Stack<TreeNode> s1 = new Stack<TreeNode>();
    Stack<TreeNode> s2 = new Stack<TreeNode>();
    s1.push(root.left);
    s2.push(root.right);

    while (!(s1.isEmpty() || s2.isEmpty())) {
        t1 = s1.pop();
        t2 = s2.pop();
        if (t1 == null && t2 == null) continue;
        if (t1 == null && t2 != null || t1 != null && t2 == null) return false;
        if (t1.val == t2.val) {
            s1.push(t1.left);
            s1.push(t1.right);
            s2.push(t2.right);
            s2.push(t2.left);
        }else return false;
    }
    if (s1.isEmpty() && !s2.isEmpty() || s2.isEmpty() && !s1.isEmpty()) return false;       
    return true;
}

代碼二 精簡版

public boolean isSymmetric(TreeNode root) {
    Queue<TreeNode> q = new LinkedList<TreeNode>();
    if (root == null) return true;
    q.add(root.left);
    q.add(root.right);
    while (q.size() > 1) {
        TreeNode left = q.poll(), right = q.poll();
        if (left == null && right == null) continue;
        if (left == null ^ right == null) return false;
        if (left.val != right.val) return false;
        q.add(left.left);
        q.add(right.right);
        q.add(left.right);
        q.add(right.left);
    }
    return true;
}

代碼三 遞歸

public boolean isSymmetric(TreeNode root) {
    return root==null || isSymmetricHelp(root.left, root.right);
}

private boolean isSymmetricHelp(TreeNode t1, TreeNode t2) {
    if (t1 == null || t2 == null) return t1 == t2;
    if (t1.val != t2.val) return false;
    return isSymmetricHelp(t1.left, t2.right) && isSymmetricHelp(t1.right, t2.left);
    }

104. Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.


代碼一 自己寫的

public int maxDepth(TreeNode root) {
    return bfs(root, 0);

}

int bfs(TreeNode node, int depth) {
    if (node == null) return depth;
    return Math.max(bfs(node.left, depth + 1), bfs(node.right, depth + 1));
}

代碼二 精簡版 16%
思維還是跟不上迭代的精髓,根本不需要一個變量去傳遞depth

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}

111. Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.


public int minDepth(TreeNode root) {
    if (root == null) return 0;
    int left = minDepth(root.left);
    int right = minDepth(root.right);
    return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1;
}

102. Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
return its level order traversal as:
[
  [3],
  [9,20],
  [15,7]
]

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> re=new LinkedList<List<Integer>>();
    if(root==null) return re;
    Queue<TreeNode> queue=new ArrayDeque<TreeNode>();
    queue.add(root);
    
    while(!queue.isEmpty()){
        int size=queue.size();
        List<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<size;i++){
            TreeNode node=queue.poll();
            list.add(node.val);
            if(node.left!=null) queue.add(node.left);
            if(node.right!=null) queue.add(node.right);
        }
        re.add(list);
    }
    return re;
}

103. Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
return its zigzag level order traversal as:
[
  [3],
  [20,9],
  [15,7]
]

代碼一 3%

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> re = new LinkedList<List<Integer>>();
    if (root == null) return re;
    Stack<TreeNode> stack= new Stack<TreeNode>();
    Stack<TreeNode> next= new Stack<TreeNode>();
    stack.push(root);
    boolean flag = true;

    while (!stack.isEmpty()) {
        int size = stack.size();
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < size; i++) {
            TreeNode node = stack.pop();
            list.add(node.val);
            if (flag) {
                if (node.left != null) next.push(node.left);
                if (node.right != null) next.push(node.right);
            } else {
                if (node.right != null) next.push(node.right);
                if (node.left != null) next.push(node.left);
            }
        }
        stack=next;
        next= new Stack<TreeNode>();
        flag = !flag;
        re.add(list);
    }
    return re;
}

代碼二 40%
從左到右遍歷就可以了,只是在做list的時候反向插入即可。

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> re=new LinkedList<List<Integer>>();
    if(root==null) return re;
    Queue<TreeNode> queue=new ArrayDeque<TreeNode>();
    queue.add(root);
    boolean flag = true;
    
    while(!queue.isEmpty()){
        int size=queue.size();
        List<Integer> list=new ArrayList<Integer>();
        for(int i=0;i<size;i++){
            TreeNode node=queue.poll();
            if(flag) list.add(node.val);
            else list.add(0, node.val);
            if(node.left!=null) queue.add(node.left);
            if(node.right!=null) queue.add(node.right);
        }
        flag!=flag;
        re.add(list);
    }
    return re;
}

105. Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.


代碼一 75%
http://blog.csdn.net/crazy1235/article/details/51559645

public TreeNode buildTree(int[] preorder, int[] inorder) {
    return build(preorder, inorder, 0, 0, inorder.length - 1);
}

public TreeNode build(int[] preorder, int[] inorder, int preIndex, int startInIndex, int endInIndex) {
    if (startInIndex > endInIndex) return null;
    int index = getIndexInInorder(inorder, preorder[preIndex]);
    int LenL = index - startInIndex;
    int LenR = endInIndex - index;
    TreeNode node = new TreeNode(preorder[preIndex]);
    if (LenL > 0) node.left = build(preorder, inorder, preIndex + 1, startInIndex, index - 1);
    if (LenR > 0) node.right = build(preorder, inorder, preIndex + LenL + 1, index + 1, endInIndex);
    return node;

}

public int getIndexInInorder(int[] inorder, int val) {
    for (int i = 0; i < inorder.length; i++) {
        if (val == inorder[i]) {
            return i;
        }
    }
    return -1;
}

108. Convert Sorted Array to Binary Search Tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.


代碼一:遞歸

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
 
public TreeNode sortedArrayToBST(int[] nums) {
    if(nums.length==0) return null;
    TreeNode head=build(nums,0,nums.length-1);
    return head;
}

TreeNode build(int[] nums, int lo, int hi){
    if( lo > hi ) return null;
    int mid = ( lo + hi ) / 2;
    TreeNode node = new TreeNode( nums[mid] );
    node.left = build( nums, lo, mid-1 );
    node.right = build( nums, mid + 1, hi );
    return node;
}

代碼二:非遞歸
public TreeNode sortedArrayToBST(int[] nums) {

        int len = nums.length;
        if ( len == 0 ) { return null; }
        
        // 0 as a placeholder
        TreeNode head = new TreeNode(0); 
        
        Deque<TreeNode> nodeStack       = new LinkedList<TreeNode>() {{ push(head);  }};
        Deque<Integer>  leftIndexStack  = new LinkedList<Integer>()  {{ push(0);     }};
        Deque<Integer>  rightIndexStack = new LinkedList<Integer>()  {{ push(len-1); }};
        
        while ( !nodeStack.isEmpty() ) {
            TreeNode currNode = nodeStack.pop();
            int left  = leftIndexStack.pop();
            int right = rightIndexStack.pop();
            int mid   = left + (right-left)/2; // avoid overflow
            currNode.val = nums[mid];
            if ( left <= mid-1 ) {
                currNode.left = new TreeNode(0);  
                nodeStack.push(currNode.left);
                leftIndexStack.push(left);
                rightIndexStack.push(mid-1);
            }
            if ( mid+1 <= right ) {
                currNode.right = new TreeNode(0);
                nodeStack.push(currNode.right);
                leftIndexStack.push(mid+1);
                rightIndexStack.push(right);
            }
        }
        return head;
    }

109. Convert Sorted List to Binary Search Tree

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
造樹,和上面的區(qū)別是沒辦法通過索引直接獲得了。


代碼一 遞歸
自頂向上

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if (head==null) return null;
        ListNode slow=head;
        ListNode fast=head;
        ListNode prev=null;
        while(fast!=null && fast.next!=null){
            prev=slow;
            slow=slow.next;
            fast=fast.next.next;
        }
        
        TreeNode root=new TreeNode(slow.val);
        
        if(prev!=null){
            prev.next=null;
        }else
            head=null;
            
        root.left=sortedListToBST(head);
        root.right=sortedListToBST(slow.next);
        return root;
    }
}

代碼二 遞歸
中序遍歷(待探究) 自底向上
左結(jié)點,根,右結(jié)點

private ListNode node;

public TreeNode sortedListToBST(ListNode head) {
    if(head == null){
        return null;
    }
    
    int size = 0;
    ListNode runner = head;
    node = head;
    
    while(runner != null){
        runner = runner.next;
        size ++;
    }
    
    return inorderHelper(0, size - 1);
}

public TreeNode inorderHelper(int start, int end){
    if(start > end){
        return null;
    }
    int mid = start + (end - start) / 2;
    
    TreeNode left = inorderHelper(start, mid - 1);
    treenode.left = left;
    
    TreeNode treenode = new TreeNode(node.val);
    node = node.next;

    TreeNode right = inorderHelper(mid + 1, end);
    treenode.right = right;
    
    return treenode;
}

114. Flatten Binary Tree to Linked List

Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
        / \
       2   5
      / \   \
     3   4   6
The flattened tree should look like:
   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6

代碼一 從左向右

  1. 如果當(dāng)前結(jié)點為葉結(jié)點,則返回該結(jié)點
  2. 如果左子樹不為空,給左子樹排序,找到左子樹的最右下點node,node.right=右子樹,繼續(xù)給右子樹排序。
  3. 如果左子樹為空。(有可能它是整個左子樹的一部分),返回該左子樹的最右下端。
public void flatten(TreeNode root) {
    if(root ==null) return;
    dfs(root);
}

TreeNode dfs(TreeNode root){
    if(root.left==null && root.right==null) return root;
    if(root.left==null) {
        return dfs(root.right);
    }
    
    TreeNode node=dfs(root.left);
    node.right=root.right;
    root.right=root.left;
    root.left=null;
    return dfs(root.right);
}

代碼二 精簡版
從右到左,從下到上

private TreeNode prev = null;

public void flatten(TreeNode root) {
    if (root == null)
        return;
    flatten(root.right);
    flatten(root.left);
    root.right = prev;
    root.left = null;
    prev = root;
}

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.

Return the sum = 12 + 13 = 25.

public int sumNumbers(TreeNode root) {
    return dfs(root,0);
}

int dfs(TreeNode node, int val){
    if(node==null) return 0;
    int sum=10*val+node.val;
    if(node.left==null && node.right==null) return sum;
    return dfs(node.left,sum)+dfs(node.right,sum);
    
}

112. Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

For example:
Given the below binary tree and sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.    

代碼一 自己寫的
左右枝一片混亂
一直在犯同一個錯誤,如果左枝為空,并不能通過左枝來判斷,因為左枝根本不是葉結(jié)點!!!,應(yīng)該只看右枝; 同樣地,如果右枝為空,只看左枝

public boolean dfs(TreeNode root, int sum) {
    if(root==null) return sum==0;
    if(root.left!=null ) {//如果左枝不為空
        boolean flag=dfs(root.left, sum-root.val); //看一眼
        if(flag) return true; //如果找到了直接返回
        else if (root.right!=null){//如果右枝不為空
            return dfs(root.right,sum-root.val); //返回右枝
        }else return false;//如果右枝為空,則根本不用看右枝了
            
    }
    return dfs(root.right, sum-root.val); //如果左枝為空,則看右枝
}


代碼二 人家寫的,如此簡潔
我是到空了,再判斷。
人家是在父結(jié)點判斷即可。如果左右枝都為空,直接判斷,不再往下走。
想法和Q129一樣的,我自己傻掉了。再鞏固,學(xué)習(xí)。

public boolean hasPathSum(TreeNode root, int sum) {
    if(root == null) return false;

    if(root.left == null && root.right == null && sum - root.val == 0) return true;

    return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}


113. Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

For example:
Given the below binary tree and sum = 22,
              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1
return
[
   [5,4,11,2],
   [5,8,4,5]
]

代碼一 15%

public List<List<Integer>> pathSum(TreeNode root, int sum) {
    List<List<Integer>> re = new LinkedList<List<Integer>>();
    dfs(re,new ArrayList<Integer>(),root,sum);
    return re;
}

void dfs(List<List<Integer>> re,List<Integer> list, TreeNode node, int sum){
    if(node==null) return;
    int n=node.val;
    List<Integer> newList=new ArrayList<Integer>(list);
    newList.add(n);
    if(node.left==null && node.right==null){
        if(sum==n){
            re.add(newList);
        }
        else return;
    }
    
    dfs(re, newList,node.left,sum-n);
    dfs(re, newList,node.right,sum-n);
}

代碼二 48%
微調(diào)整,不是每次重新創(chuàng)立新的list,而是在最后的時候remove就可以了

public List<List<Integer>> pathSum(TreeNode root, int sum) {
    List<List<Integer>> re = new LinkedList<List<Integer>>();
    dfs(re, new ArrayList<Integer>(), root, sum);
    return re;
}

void dfs(List<List<Integer>> re, List<Integer> list, TreeNode node, int sum) {
    if (node == null) return;
    int n = node.val;
    list.add(n);
    if (node.left == null && node.right == null && sum == n) {
        List<Integer> newList = new ArrayList<Integer>(list);
        re.add(newList);

    } else {
        dfs(re, list, node.left, sum - n);
        dfs(re, list, node.right, sum - n);
    }
    list.remove(list.size() - 1);
}

437. Path Sum III

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:

1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

代碼一 3% 自己寫的bullshit。 新建map太花時間了。我記錄的是減法,實際記錄加法就可以了。這樣就不用每次新建map了。

int count=0;
public int pathSum(TreeNode root, int sum) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    map.put(sum, 1);//這個寫在哪里一開始沒有想清楚
    dfs(root, map, sum);
    return count;
}

void dfs(TreeNode node, Map<Integer, Integer> map, int sum) {
    if (node == null) return;

    int cur = node.val;
    //不要在這里加,因為不好減
    if (map.containsKey(cur)) {
        count += map.get(cur);
    }

    if (node.left == null && node.right == null) return;
    Map<Integer, Integer> curMap = new HashMap<Integer, Integer>();

    for (int target : map.keySet()) {
        curMap.put(target - cur, map.get(target));
    }
    curMap.put(sum, curMap.getOrDefault(sum, 0)+1);//在這里加
    dfs(node.left,curMap,sum);
    dfs(node.right,curMap,sum);
    curMap.put(sum, curMap.get(sum)-1);//在這里減
}

代碼二 68% 記錄加法

public int pathSum(TreeNode root, int sum) {
    HashMap<Integer, Integer> preSum = new HashMap();
    preSum.put(0, 1);
    return helper(root, 0, sum, preSum);
}

public int helper(TreeNode root, int currSum, int target, HashMap<Integer, Integer> preSum) {
    if (root == null) return 0;

    currSum += root.val;
    int res = preSum.getOrDefault(currSum - target, 0);
    preSum.put(currSum, preSum.getOrDefault(currSum, 0) + 1);
    
    res += helper(root.left, currSum, target, preSum) + helper(root.right, currSum, target, preSum);
    preSum.put(currSum, preSum.get(currSum) - 1);
    return res;
}

代碼三 46% 真正的迭代

public int pathSum(TreeNode root, int sum) {
    if (root == null) return 0;
    return pathSumFrom(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
    }
    
private int pathSumFrom(TreeNode node, int sum) {
    if (node == null) return 0;
    return (node.val == sum ? 1 : 0) 
        + pathSumFrom(node.left, sum - node.val) + pathSumFrom(node.right, sum - node.val);
    }

257. Binary Tree Paths

Given a binary tree, return all root-to-leaf paths.

For example, given the following binary tree:

   1
 /   \
2     3
 \
  5
All root-to-leaf paths are:

["1->2->5", "1->3"]

代碼一 15%

public List<String> binaryTreePaths(TreeNode root) {
    List<String> re = new LinkedList<String>();
    if (root == null) return re;
    if (root.left == null & root.right == null) {
        re.add(String.valueOf(root.val));
        return re;
    }
    bfs(root.left, re, String.valueOf(root.val));
    bfs(root.right, re, String.valueOf(root.val));
    return re;
}

void bfs(TreeNode node, List<String> list, String s) {
    if (node == null) {
        return;
    }
    s += "->" + node.val;
    if (node.left == null && node.right == null) {
        list.add(s);
        return;
    }

    bfs(node.left, list, s);
    bfs(node.right, list, s);

}

代碼二 3%

public List<String> binaryTreePaths(TreeNode root) {
    List<String> answer = new ArrayList<String>();
    if (root != null) searchBT(root, "", answer);
    return answer;
}
private void searchBT(TreeNode root, String path, List<String> answer) {
    if (root.left == null && root.right == null) answer.add(path + root.val);
    if (root.left != null) searchBT(root.left, path + root.val + "->", answer);
    if (root.right != null) searchBT(root.right, path + root.val + "->", answer);
}

116. Populating Next Right Pointers in Each Node

Given a binary tree

class TreeLinkNode {
  TreeLinkNode *left;
  TreeLinkNode *right;
  TreeLinkNode *next;
}

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,
         1
       /  \
      2    3
     / \  / \
    4  5  6  7
After calling your function, the tree should look like:
         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

代碼一 16% 不符合要求

public void connect(TreeLinkNode root) {
    if (root == null) return;
    Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
    q.offer(root);
    while (!q.isEmpty()) {
        Queue<TreeLinkNode> next = new LinkedList<TreeLinkNode>();
        int size = q.size();
        for (int i = 0; i < size; i++) {
            TreeLinkNode node = q.poll();
            node.next = q.peek();
            if (node.left != null) next.offer(node.left);
            if (node.right != null) next.offer(node.right);
        }
        q = next;
    }
}

代碼二 29%

public void connect(TreeLinkNode root) {
    if (root == null) return;
    TreeLinkNode cur = root;
    TreeLinkNode nextLeftmost = null;

    while (cur.left != null) {//往下走
        nextLeftmost = cur.left; // save the start of next level
        while (cur != null) {//往右走
            cur.left.next = cur.right;
            cur.right.next = cur.next == null ? null : cur.next.left;
            cur = cur.next;
        }
        cur = nextLeftmost; // point to next level
    }
}

代碼三 75%

public void connect(TreeLinkNode root) {
    if(root==null) return;    
    if(root.left!=null) {
        root.left.next=root.right;
        connect(root.left);
    }
    if(root.next!=null && root.right!=null){
        root.right.next=root.next.left;
    }  
    connect(root.right);
}

117. Populating Next Right Pointers in Each Node II

Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

You may only use constant extra space.

For example,
Given the following binary tree,
         1
       /  \
      2    3
     / \    \
    4   5    7
After calling your function, the tree should look like:
         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL

代碼 50%

public void connect(TreeLinkNode root) {
    if (root == null) return;
    TreeLinkNode head = new TreeLinkNode(0);
    TreeLinkNode cur = head;

    while (root != null) {// 這個循環(huán)既是往右走,又是往下走
        if (root.left != null) {
            cur.next = root.left;// 神來之筆
            cur = cur.next;
        }
        if (root.right != null) {
            cur.next = root.right;
            cur = cur.next;
        }
        root = root.next;
        if (root == null) {
            root = head.next;
            cur = head;
            head.next = null;
        }
    }
}

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

For example,

    1
   / \
  2   3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.

Return the sum = 12 + 13 = 25.

代碼一 遞歸59%

public int sumNumbers(TreeNode root) {
    return dfs(root,0);
}

int dfs(TreeNode node, int val){
    if(node==null) return 0;
    int sum=10*val+node.val;
    if(node.left==null && node.right==null) return sum;
    return dfs(node.left,sum)+dfs(node.right,sum);
    
}

440. 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.

分析
依次逐漸確定前綴,每次計算當(dāng)前前綴下不超過n的個數(shù),若個數(shù)超過k,則說明第k個數(shù)在當(dāng)前前綴下,反之,則說明在當(dāng)前前綴加1以后的前綴;

以first為前綴的數(shù)
[first, first+1]
[first10, (first+1)10]
[first100, (first+1)100]

另一種分析方法,這是一顆十叉樹,前序遍歷(然而不用真的遍歷,只需要計算子樹的大小即可)

public int findKthNumber(int n, int k) {  
    int ans=1;  
    for(k--;k>0;){  
        int count=0;  
        for(long first=ans,second=first+1;first<=n;first*=10,second*=10){  
            count+=Math.min(n+1,second)-first;  
        }  
        if(count<=k){  
            k-=count;  
            ans++;  
        }else{  
            k--;//減掉的是當(dāng)前為前綴的那個數(shù)  
            ans*=10;//元素個數(shù)太多,需要減小,因此前綴變大  
        }  
    }  
    return ans;  
}  

自己更習(xí)慣用gap,其實是一樣的,不過上面寫的更精簡一點
每次的形式都為[first, first+gap],每次循環(huán)跟新first和gap
[4, 4+1] ----> gap=1,first=4
[410, 410+10]----> gap=10, first=40
[4100, 4100+100]----> gap=100, first=400

public int findKthNumber(int n, int k) {
    long size = 1;
    int cur = 1;
    k--;

    while (k != 0) {
        size = getSize(cur, n);
        if (size > k) {
            cur = cur * 10;
            k--;
        } else {
            cur++;
            k -= size;
        }
    }
    return cur;
}

long getSize(long cur, long n){
    long count=0;
    long gap=1;
    while(cur<=n){
        count+=Math.min(gap, n-cur+1);
        gap*=10;
        cur*=10;
    }
    return count;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內(nèi)容