Monday, September 7, 2015

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"]
Solution: DFS

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List binaryTreePaths(TreeNode root) {
        ArrayList result = new ArrayList();

        if (root == null) {
            return result;
        }
        
        dfs(root, result, new StringBuilder());

        return result;
    }
    
    public void dfs(TreeNode root, ArrayList result, StringBuilder path) {
        if (root.left == null && root.right == null) {
            path.append(root.val);
            result.add(path.toString());
            return;
        }
        
        path.append(root.val);
        path.append("->");
        
        if (root.left != null) {
            dfs(root.left, result, new StringBuilder(path));
        }
        
        if (root.right != null) {
            dfs(root.right, result, new StringBuilder(path));
        }
    }
}

Friday, September 4, 2015

Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
For example:
Given num = 38, the process is like: 3 + 8 = 111 + 1 = 2. Since 2 has only one digit, return it.
Follow up:
Could you do it without any loop/recursion in O(1) runtime?
Solution1: with while loop
public class Solution {
    public int addDigits(int num) {
        if (num < 10) {
            return num;
        }
        
        int res = 0;
        while (num / 10 >= 1) {
            res = 0;
            res += num % 10;
            num = num / 10;
            res += num;
            num = res;
        }
        return res;
    }
}
Solution2: 观察得出规律,
if (in % 9 != 0) return in % 9;
else return 9;
public class Solution {
    public int addDigits(int num) {
        if (num == 0) {
            return 0;
        }
        
        if (num % 9 != 0) {
            return num % 9;
        } else {
            return 9;
        }
    }
}
Or:
public class Solution {
    public int addDigits(int num) {
        return (num - 1) % 9 + 1;
    }
}

Thursday, September 3, 2015

Count Primes

Count the number of prime numbers less than a non-negative number, n.
Solution1: 超时了
public class Solution {
    public int countPrimes(int n) {
        int count = 0;
        
        for (int i = 2; i <= n; i++) {
            if (isPrime(i)) {
                count++;
            }
        }
        return count;
    }
    
    public boolean isPrime(int x) {
        for (int i = 2; i <= Math.sqrt(x); i++) {
            if (x % i == 0) {
                return false;
            }
        }
        return true;
    }
}
Run time complexity is O(n log log n), space complexity is O(n)
public class Solution {
    public int countPrimes(int n) {
        int result = 0;
        
        boolean[] notPrime = new boolean[n];
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (!notPrime[i]) {
                int j = i * i;
                while (j < n) {
                    notPrime[j] = true;
                    j += i;
                } 
            }
        }
        
        for (int i = 2; i < n; i++) {
            if (!notPrime[i]) {
                result++;
            }
        }
        
        return result;
    }
}
Or: 更加清晰一点
public class Solution {
    public int countPrimes(int n) {
        int result = 0;
        
        boolean[] isPrime = new boolean[n];
        for(int i = 0; i < n; i++) {
            isPrime[i] = true;
        }
        
        // Loop's ending condition is i * i < n instead of i < sqrt(n)
        // to avoid repeatedly calling an expensive function sqrt().
        for (int i = 2; i * i < n; i++) {
            if (isPrime[i]) {
                int j = i * i;
                while (j < n) {
                    isPrime[j] = false;
                    j += i;
                } 
            }
        }
        
        for (int i = 2; i < n; i++) {
            if (isPrime[i]) {
                result++;
            }
        }
        
        return result;
    }
}

Tuesday, September 1, 2015

Ugly Number

Write a program to check whether a given number is an ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7.
Note that 1 is typically treated as an ugly number.
Solution1: recursive
public class Solution {
    public boolean isUgly(int num) {
        if (num < 1) {
            return false;
        }
        
        if (num == 1) {
            return true;
        }
        
        if (num % 2 == 0) {
            return isUgly(num / 2);
        }
        
        if (num % 3 == 0) {
            return isUgly(num / 3);
        }
        
        if (num % 5 == 0) {
            return isUgly(num / 5);
        }
        
        return false;
    }
}
Solution2: iterative
public class Solution {
    public boolean isUgly(int num) {
        int div = 2 * 3 * 5;
        
        while (num > 0 && div > 1) {
            if (num % div == 0) {
                num /= div;
            }
            
            if (num % 2 != 0 && div % 2 == 0) {
                div /= 2;
            }
            
            if (num % 3 != 0 && div % 3 == 0) {
                div /= 3;
            }
            
            if (num % 5 != 0 && div % 5 == 0) {
                div /= 5;
            }
        }
        
        return num == 1;
    }
}

Friday, August 28, 2015

Happy Number

Write an algorithm to determine if a number is "happy".
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
  • 12 + 92 = 82
  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1
Solution: 线性的复杂度O(n)
public class Solution {
    public boolean isHappy(int n) {
        HashSet set = new HashSet<>();
        
        while (!set.contains(n)) {
            set.add(n);
            n = sum(getDigit(n));
            if (n == 1) {
                return true;
            }
        }
        return false;
    }
    
    public int sum(int[] arr) {
        int sum = 0;
        for(int i : arr) {
            sum += i * i;
        }
        return sum;
    }
    
    public int[] getDigit(int n) {
        String s = String.valueOf(n);
        
        int[] arr = new int[s.length()];
        int i = 0;
        while (n >= 1) {
            int m = n % 10;
            arr[i] = m;
            i++;
            n = n / 10;
        }
        return arr;
    }
}

Wednesday, August 26, 2015

Contains Duplicate II

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k.
Solution: Run time complexity is O(n), space complexity is O(n).
public class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        HashMap map = new HashMap<>();
        
        for(int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                int pre = map.get(nums[i]);
                if (i - pre <= k) {
                    return true;
                }
            }
            map.put(nums[i], i);
        }
        
        return false;
    }
}

Contains Duplicate

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
Solution1: Run time complexity of Arrays.sort is O(nlogn), so total run time complexity is O(nlogn), constant space. 
public class Solution {
    public boolean containsDuplicate(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return false;
        }
        
        Arrays.sort(nums);
        
        int i = 0;
        int j = i + 1;
        
        while (j < nums.length) {
            if (nums[i] == nums[j]) {
                return true;
            } else {
                i++;
                j++;
            }
        }
        return false;
    }
}
Solution2: Run time complexity is O(n), space complexity is O(n).
public class Solution {
    public boolean containsDuplicate(int[] nums) {
        if (nums == null || nums.length <= 1) {
            return false;
        }
        
        HashSet set = new HashSet();
        for (int i = 0; i < nums.length; i++) {
            if (set.contains(nums[i])) {
                return true;
            } else {
                set.add(nums[i]);
            }
        }
        return false;
    }
}
Or
public class Solution {
    public boolean containsDuplicate(int[] nums) {
        if (nums == null || nums.length == 0) {
            return false;
        }
        
        HashSet set = new HashSet();
        for (int i : nums) {
            if (!set.add(i)) {
                return true;
            }
        }
        return false;
    }
}