显示标签为“Leetcode”的博文。显示所有博文
显示标签为“Leetcode”的博文。显示所有博文

2016年7月14日星期四

[笔记整理] 九章算法第二章 Binary Search & Sorted Array Part2

1. Search for a Range
<=> How many times did a number appear?  range[x1, x2] => x2-x1+1

* The insertion position may not be in current array
* Find the insertion position, 3 positions to check: x<start, start<x<end, x>end


* No duplicate
* 2 possible position for mid: [mid] >= [0], [mid] < [0]
* 4 possible position for target: [0]<T<[mid], [0]<[mid]<T, T<[mid]<[0], [mid]<T<[0]

* Duplicate

* Worst case for binary search - O(n) e.g. If in every iteration, [mid]==[0]/[mid]==[length-1] =>O(n)

* Any element in row1 < Any element in row 2
* Use binary search for 2 times, 1st time find the row of target, 2nd time find the column of target

[1 0 2 4]
[1 2 6 9]
[3 5 7 10]
[7 8 9 11]
* Quadrate search O(n)
* Search from left bottom to right top, exclude 1 row/column each iteration, O(m + n)



* peak <=> A[p] > A[p - 1] && A[p] >A[p + 1]

9. Remove Duplicate from Sorted Array

10. Remove Duplicate from Sorted Array II

11. Merge Sorted Array

* Merge + Find O(m + n)
* Find kth largest O(logn)
when (m+n) is odd=>k=(m+n)/2+1
when (m+n) is even=>k1=(m+n)/2, k2=(m+n)/2+1
* How to find kth largest?

Throw away each k/2 elements in each iteration

* Sort, O(1) space O(nlogn) time
* 3 times reverse, O(1) space O(n) time

* abcdefg, offset=3 => efgabcd

* reverse each word, then reverse the entire string


2015年8月15日星期六

[LeetCode] Binary Tree Paths

Problem:

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"]

Java Code:

/**
 * 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<String> binaryTreePaths(TreeNode root) {
        List<String> result = new ArrayList<String>();
        if (root == null) {
            return result;
        }
        
        List<Integer> path = new ArrayList<Integer>();
        helper(root, path, result);
        return result;
    }
    
    private void helper(TreeNode root, List<Integer> path, List<String> result) {
        path.add(root.val);
        if (root.left != null) {
            helper(root.left, path, result);
        }
        if (root.right != null) {
            helper(root.right, path, result);
        } 
        if (root.left == null && root.right == null) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < path.size(); i++) {
                sb.append(path.get(i));
                if (i != path.size() - 1) {
                    sb.append("->");
                }
            }
            result.add(new String(sb));
        }
        path.remove(path.size() - 1);
    }
}

这个递归解法感觉有些复杂了,有没有更简单的解法呢?

2015年7月27日星期一

[LeetCode] Different Ways to Add Parentheses

Java Code:

public class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> result = new ArrayList<Integer>();
        if (input == null || input.length() == 0) {
            return result;
        }
        
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c != '+' && c != '-' && c != '*') {
                continue;
            }
            
            List<Integer> part1Result = 
                diffWaysToCompute(input.substring(0, i));
            List<Integer> part2Result = 
                diffWaysToCompute(input.substring(i + 1, input.length()));
            
            for (Integer m : part1Result) {
                for (Integer n : part2Result) {
                    if (c == '+') {
                        result.add(m + n);
                    } else if (c == '-') {
                        result.add(m - n);
                    } else if (c == '*') {
                        result.add(m * n);
                    }
                }
            }
        }
        
        if (result.size() == 0) {
            result.add(Integer.parseInt(input));
        }
        
        return result;
    }
}

reference:
https://leetcode.com/discuss/48477/a-recursive-java-solution-284-ms

[LeetCode] Search a 2D Matrix II

Java Code:

public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 
            || matrix[0].length == 0) {
            return false;
        }
        
        int i = 0;
        int j = matrix[0].length - 1;
        
        while (i < matrix.length && j >= 0) {
            if (matrix[i][j] == target) {
                return true;
            } else if (matrix[i][j] < target) {
                i++;
            } else {
                j--;
            }
        }
        
        return false;
    }
}

reference:
https://leetcode.com/discuss/47660/my-java-solution-using-binary-search

2015年7月24日星期五

[LeetCode] Maximum Product Subarray

Problem:

Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.

Java Code:

public class Solution {
    public int maxProduct(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        
        int result = nums[0];
        int[] maxProduct = new int[nums.length];
        int[] minProduct = new int[nums.length];
        maxProduct[0] = nums[0];
        minProduct[0] = nums[0];
        
        for (int i = 1; i < nums.length; i++) {
            int[] tmp = new int[3];
            tmp[0] = nums[i];
            tmp[1] = nums[i] * maxProduct[i - 1];
            tmp[2] = nums[i] * minProduct[i - 1];
            
            Arrays.sort(tmp);
            
            result = Math.max(result, tmp[2]);
            maxProduct[i] = tmp[2];
            minProduct[i] = tmp[0];
        }
        
        return result;
    }
}

reference: https://leetcode.com/discuss/41102/share-accepted-dp-java-o-n-solution

2015年7月20日星期一

[LeetCode][面试未完成题目之魔咒] Longest Substring with At Most Two Distinct Characters

Problem:

Given a string S, find the length of the longest substring T that contains at most two distinct characters.
For example,
Given S = “eceba”,
T is “ece” which its length is 3.

Thinking:

维护一个变量 i,表示当前检测的substring ( with two distinct characters )的起始位置(k为终止位置)。
引入一个变量 j,表示更早结束出现的那一个character的最后一次出现的位置,这个变量是为了更新 i 而设置的,当 i 的值需要更新的时候(即遇到不是当前这两种字符的字符),i = j + 1,更新 i 的值之前更新maxLength。

举个例子(关于i,j,k的位置):

a b b a c c
i     j    k

a b b c c
i        k
j

Java Code:

public class Solution {
     public static int lengthOfLongestSubstringWithTwoDistinct(String s) {
         if (s == null || s.length() == 0) {
             return 0;
         }
         
         int i = 0;//start of current substring
         int j = -1;//更早结束出现的那一个字符最后一次出现的位置(为更新i使用)
         int maxLength = 0;
         
         for (int k = 1; k < s.length(); k++) {
             if (s.charAt(k) == s.charAt(k - 1)) {
                 continue;
             }
             
             if (j >= 0 && s.charAt(j) != s.charAt(k)) {
                 maxLength = Math.max(maxLength, k - i);
                 i = j + 1;
             }
             j = k - 1;
         }
         
         maxLength = Math.max(maxLength, s.length() - i);
         
         return maxLength;
     }
    
    
    public static void main(String[] args) {
        System.out.println(lengthOfLongestSubstringWithTwoDistinct("aab"));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct("aabb"));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct("abbacc"));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct("abbcc"));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct("a"));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct(""));
        System.out.println(lengthOfLongestSubstringWithTwoDistinct(null));
    }
}

reference: http://www.danielbit.com/blog/puzzle/leetcode/leetcode-longest-substring-with-at-most-two-distinct-characters

(脑洞:个人感觉这道题并不适合用“滑动窗口”的概念来解释,因为滑动窗口的感觉需要维护窗口的起始和终止两个变量的,而这道题目只需要维护一个变量i,因此一开始看sliding window的解释的时候很困惑,
关于滑动窗口协议:http://www.cnblogs.com/ulihj/archive/2011/01/06/1927613.html
更早结束出现的那一个character的最后一次出现的位置这句话说起来很拧巴,但是还没想出更好的表述)


2015年7月19日星期日

[LeetCode] Shortest Palindrome

Problem:

Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.
For example:
Given "aacecaaa", return "aaacecaaa".
Given "abcd", return "dcbabcd".

Thinking:

Find out the length of longest prefix palindrome of S.
Then, the shortest palindrome would be:
reverse(s.substring(length, s.length())) + s.

Java Code:

Version 1: Time Limit Exceeded
    public String shortestPalindrome(String s) {
        if (s == null || s.length() == 0) {
            return "";
        }
        
        //find the longest prefix
        int prefix_l = 1;
        for (int i = 1; i < s.length(); i++) {
            if (isPalindrome(s, 0, i)) {
                prefix_l = i + 1;
            }
        }
        return new String(new StringBuffer(s.substring(prefix_l, s.length())).reverse().toString() + s);
    }
    
    private boolean isPalindrome(String s, int start, int end) {
        while (start < end) {
            if (s.charAt(start) == s.charAt(end)) {
                start++;
                end--;
            } else {
                return false;
            }
        }
        return true;
    }

Version 2 (Version 1 optimized): Accepted
Optimization of the process of finding the longest prefix palindrome.
for each index i (i < s.length()/2), generate the smallest start and largest end which could make s.substring(start, end) a palindrome. If start == 0, then it is a prefix palindrome.

reference: https://leetcode.com/discuss/36807/c-8-ms-kmp-based-o-n-time-%26-o-n-memory-solution
    public String shortestPalindrome(String s) {
        if (s == null || s.length() == 0) {
            return "";
        }
        
        //find the longest prefix
        int prefix_l = 1;
        for (int i = 0; i < s.length(); ) {
            int start = i;
            int end = i;
            while (end < s.length() - 1 
                   && s.charAt(end) == s.charAt(end + 1)) {
                end++;
            }
            i = end + 1;
            while (start > 0 && end < s.length() - 1 
                   && s.charAt(start - 1) == s.charAt(end + 1)) {
                start--;
                end++;
            }
            if (start == 0 && end - start + 1 > prefix_l) {
                prefix_l = end -start + 1;
            }
        }
        
        //construct shortest palindrome
        return new String(new StringBuffer(s.substring(prefix_l, s.length())).reverse().toString() + s);
    }

2015年7月6日星期一

[LeetCode] Implement Queue using Stacks

脑洞:做到150/216了。面试遇到过这道题了,当时有个follow up question想了很久才答上来,好像是:你现在push是O(1),pop的worse case是O(n)的,如果要保证pop是O(1),你要怎么做?(在push不必须是O(1)的情况下)


Problem:

Implement the following operations of a queue using stacks.
push(x) -- Push element x to the back of queue.
pop() -- Removes the element from in front of queue.
peek() -- Get the front element.
empty() -- Return whether the queue is empty.

Java Code:

class MyQueue {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    // Push element x to the back of queue.
    public void push(int x) {
        stack1.push(x);
    }

    // Removes the element from in front of queue.
    public void pop() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.pop());
            }
        }
        stack2.pop();
    }

    // Get the front element.
    public int peek() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

    // Return whether the queue is empty.
    public boolean empty() {
        return (stack1.empty() && stack2.empty());
    }
}

2015年7月1日星期三

[LeetCode] Kth Smallest Element in a BST

Problem:

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.
https://leetcode.com/problems/kth-smallest-element-in-a-bst/


Thinking:

The kth smallest node is the left child's left child...(all the way to leaf node) of the right child of the (k - 1) th node in a binary search tree.


C++ Code:(脑洞:刚开始写C++,代码风格好像怪怪的)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        stack<TreeNode*> nodes;
        if(root == NULL) return -1;
        while(true){
            while(root!=NULL){
                nodes.push(root);
                root=root->left;
            }
            TreeNode* node=nodes.top();
            nodes.pop();
            if(k==1) return node->val;
            else {
                root=node->right;
                k--;
            }
        }
    }
};

Java Code (Using Divide and Conquer):

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int kthSmallest(TreeNode root, int k) {
        int leftCount = countNodes(root.left) + 1;
        if (leftCount == k) {
            return root.val;
        } else if (leftCount > k) {
            return kthSmallest(root.left, k);
        } else {
            return kthSmallest(root.right, k - leftCount);
        }
    }
    
    private int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

2015年6月29日星期一

[LeetCode] Majority Element II

Problem:

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Thinking:

这道题和LintCode的Majority Number II很像,但是稍有不同,需要考虑一个特殊情况:

Input:
[1,2]
Expected:
[1,2]

When there are two different elements in the array, both of the two elements appear more than n/3 times.

Java Code (写得这么长T_T):

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> result = new ArrayList<Integer>();
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        int candidate1 = 0;
        int candidate2 = 0;
        int count1 = 0;
        int count2 = 0;
        
        for (int i = 0; i < nums.length; i++) {
            if (count1 == 0) {
                candidate1 = nums[i];
            } else if (count2 == 0) {
                candidate2 = nums[i];
            }
            
            if (nums[i] == candidate1) {
                count1++;
            }
            else if (nums[i] == candidate2) {
                count2++;
            } else {
                count1--;
                count2--;
            }
        }
        
        count1 = 0;
        count2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == candidate1) {
                count1++;
            }else if (nums[i] == candidate2) {
                count2++;
            }
        }
        
        if (count1 > nums.length / 3) {
            result.add(candidate1);
        }
        if (count2 > nums.length / 3) {
            result.add(candidate2);
        }
        
        return result;
    }
}



2015年6月26日星期五

[LeetCode] Kth Largest Element in an Array

Problem:

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
Credits:
Special thanks to @mithmatt for adding this problem and creating all test cases.

Java Code:

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        if (nums == null || nums.length == 0 || k > nums.length) {
            return -1;
        }
        
        Arrays.sort(nums);
        return nums[nums.length - k];
    }
}

Explained Solutions: https://leetcode.com/discuss/36966/solution-explained

2015年6月25日星期四

[LeetCode] Summary Ranges

Problem:

Given a sorted integer array without duplicates, return the summary of its ranges.
For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"].
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.


https://leetcode.com/problems/summary-ranges/

Java Code:

public class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> result = new ArrayList<String>();
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        int pre = nums[0];
        int range = 0;
        
        for (int i = 1; i <= nums.length; i++) {
            if (i != nums.length && nums[i - 1] == nums[i] - 1) {
                range++;
            } else {
                if (range == 0) {
                    result.add(Integer.toString(pre));
                } else {
                    result.add(Integer.toString(pre) + "->" + Integer.toString(pre + range));
                }
                if (i != nums.length) {
                    pre = nums[i];
                    range = 0;
                }
            }
        }
        return result;
    }
}


2015年6月24日星期三

[LeetCode] Maximum Product Subarray

Problem:

Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.

Java Code:

public class Solution {
    public int maxProduct(int[] A) {
        if (A == null || A.length == 0) {
            return 0;
        } else if (A.length == 1) {
            return A[0];
        }
        
        int length = A.length;
        int [] sMax = new int[length];
        int [] sMin = new int[length];
        int maxProduct = A[0];
        
        sMax[0] = A[0];
        sMin[0] = A[0];
        for (int i = 1; i < length; i++) {
            sMax[i] = Math.max(Math.max(sMax[i - 1] * A[i], sMin[i - 1] * A[i]), A[i]);
            sMin[i] = Math.min(Math.min(sMax[i - 1] * A[i], sMin[i - 1] * A[i]), A[i]);
            maxProduct = Math.max(maxProduct, sMax[i]);
        }
        
        return maxProduct;
    }
}

2015年6月21日星期日

[LeetCode] Basic Calculator II

Problem:

Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, and / operators. The integer division should truncate toward zero.
You may assume that the given expression is always valid.
Some examples:
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
Note: Do not use the eval built-in library function.

Thinking:

和 #224 Basic Calculator思路基本一样,先转换为后缀式(postfix notation),然后计算后缀式的值,照抄了 #224 讨论区的一个支持*/的解法,那个链接的讲解很清楚。
(脑洞:这次是Leetcode全网第六个AC的,头一次排名这么靠前呢!虽然可以说是作弊了的T_T)


Java Code:

(ref:https://leetcode.com/discuss/39454/accepted-infix-postfix-based-solution-explaination-600ms)


public class Solution {
    int rank(char op){
        // the bigger the number, the higher the rank
        switch(op){
            case '+':return 1;
            case '-':return 1;
            case '*':return 2;
            case '/':return 2;
            default :return 0; // '(' 
        }
    }
    List<Object> infixToPostfix(String s) {
        Stack<Character> operators = new Stack<Character>();
        List<Object> postfix = new LinkedList<Object>();

        int numberBuffer = 0;
        boolean bufferingOperand = false;
        for (char c : s.toCharArray()) {
            if (c >= '0' && c <= '9') {
                numberBuffer = numberBuffer * 10 + c - '0';
                bufferingOperand = true;
            } else {
                if(bufferingOperand)
                    postfix.add(numberBuffer);
                numberBuffer = 0;
                bufferingOperand = false;

                if (c == ' '|| c == '\t')
                    continue;

                if (c == '(') {
                    operators.push('(');
                } else if (c == ')') {
                    while (operators.peek() != '(')
                        postfix.add(operators.pop());
                    operators.pop(); // popping "("
                } else { // operator
                    while (!operators.isEmpty() && rank(c) <= rank(operators.peek()))
                        postfix.add(operators.pop());
                    operators.push(c);
                }
            }

        }
        if (bufferingOperand)
            postfix.add(numberBuffer);

        while (!operators.isEmpty())
            postfix.add(operators.pop());

        return postfix;
    }

    int evaluatePostfix(List<Object> postfix) {
        Stack<Integer> operands = new Stack<Integer>();
        int a = 0, b = 0;
        for (Object s : postfix) {
            if(s instanceof Character){
                char c = (Character) s;
                b = operands.pop();
                a = operands.pop();
                switch (c) {
                    case '+': operands.push(a + b); break;
                    case '-': operands.push(a - b); break;
                    case '*': operands.push(a * b); break;
                    default : operands.push(a / b); 
                }
            }else { // instanceof Integer
                operands.push((Integer)s);
            }
        }
        return operands.pop();
    }

    public int calculate(String s) {
        return evaluatePostfix(infixToPostfix(s));
    }

}

2015年6月20日星期六

[LeetCode] The Skyline Problem

Problem:

A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).
Buildings Skyline Contour
The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
Notes:
  • The number of buildings in any input list is guaranteed to be in the range [0, 10000].
  • The input list is already sorted in ascending order by the left x position Li.
  • The output list must be sorted by the x position.
  • There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...]


Thinking:

(1) 自建一个名为Height的数据结构,保存一个building的index和height。约定,当height为负数时表示这个高度为height的building起始于index;height为正时表示这个高度为height的building终止于index。

(2) 对building数组进行处理,每一行[ Li, Ri, Hi ],根据Height的定义,转换为两个Height的对象,即,Height(Li, -Hi) 和 Height(Ri, Hi)。 将这两个对象存入heights这个List中。

(3) 写个Comparator对heights进行升序排序,首先按照index的大小排序,若index相等,则按height大小排序,以保证一栋建筑物的起始节点一定在终止节点之前。

(4) 将heights转换为结果。使用PriorityQueue对高度值进行暂存。遍历heights,遇到高度为负值的对象时,表示建筑物的起始节点,此时应将这个高度加入PriorityQueue。遇到高度为正值的对象时,表示建筑物的终止节点,此时应将这个高度从PriorityQueue中除去。且在遍历的过程中检查,当前的PriorityQueue的peek()是否与上一个iteration的peek()值(prev)相同,若否,则应在结果中加入[当前对象的index, 当前PriorityQueue的peek()],并更新prev的值。

思路是照抄这个链接的:http://www.cnblogs.com/easonliu/p/4531020.html
(脑洞:C++全忘光了,这个链接的代码好久才看懂,赶快补!)

Java Code:

public class Solution {
    public List<int[]> getSkyline(int[][] buildings) {
        List<int[]> result = new ArrayList<int[]>();
        if (buildings == null || buildings.length == 0 || buildings[0].length == 0) {
            return result;
        }
        
        List<Height> heights = new ArrayList<Height>();
        for (int[] building : buildings) {
            heights.add(new Height(building[0], -building[2]));
            heights.add(new Height(building[1], building[2]));
        }
        Collections.sort(heights, new Comparator<Height>() {
            @Override
            public int compare(Height h1, Height h2) {
                return h1.index != h2.index ? h1.index - h2.index : h1.height - h2.height;
            }
        });
        
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>(1000, Collections.reverseOrder());
        pq.offer(0);
        int prev = 0;
        for (Height h : heights) {
            if (h.height < 0) {
                pq.offer(-h.height);
            } else {
                pq.remove(h.height);
            }
            int cur = pq.peek();
            if (cur != prev) {
                result.add(new int[]{h.index, cur});
                prev = cur;
            }
        }
        
        return result;
    }
    
    class Height {
        int index;
        int height;
        Height(int index, int height) {
            this.index = index;
            this.height = height;
        }
    }
}


2015年6月17日星期三

[LeetCode] Word Break

Problem:

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".

Java Code:

public class Solution {
    public boolean wordBreak(String s, Set<String> dict) {
        //f[i]: if s.substring(0,i) can be segmented
        //f[i] = f[x] + dict.contains(s.substring(x, i)), x>0 <i
        
        if (s == null || s.length() == 0 || dict == null || dict.size() == 0) {
            return false;
        }
        
        boolean[] f = new boolean[s.length() + 1];
        f[0] = true;
        
        for (int i = 1; i <= s.length(); i++) {
            if (dict.contains(s.substring(0, i))) {
                f[i] = true;
            } else {
                for (int j = 1; j <= i; j++) {
                    f[i] = f[i] || (f[j] && dict.contains(s.substring(j, i)));
                }
            }
        }
        
        return f[s.length()];
    }
}


2015年6月16日星期二

[LeetCode] Repeated DNA Sequences

Problem:

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.
Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.
For example,
Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",
Return:
["AAAAACCCCC", "CCCCCAAAAA"].

Java Code:

public class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        List<String> result = new ArrayList<String>();
        if (s.length() < 10) {
            return result;
        }
        
        HashMap<Integer, Integer> hs = new HashMap<Integer, Integer>();
        for (int i = 0; i <= s.length() - 10; i++) {
            int current = seqToInt(s.substring(i, i + 10));
            if (!hs.containsKey(current)) {
                hs.put(current, 1);
            } else if (hs.get(current) == 1){
                result.add(intToSeq(current));
                hs.put(current, 2);
            }
        }
        
        return result;
    }
    
    private int seqToInt(String seq) {
        //A-00 C-01 G-10 T-11
        int res = 0;
        for (int i = 0; i < seq.length(); i++) {
            char a = seq.charAt(i);
            if (a == 'A') {
                res += 0;
            } else if (a == 'C') {
                res += 1;
            } else if (a == 'G') {
                res += 2;
            } else {
                res += 3;
            }
            res = res << 2;
        }
        res = res >> 2;
        return res;
    }
    
    private String intToSeq(int seq) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10; i++) {
            int cur = seq & 0x0003;
            if (cur == 0) {
                sb.insert(0, 'A');
            } else if (cur == 1) {
                sb.insert(0, 'C');
            } else if (cur == 2) {
                sb.insert(0, 'G');
            } else {
                sb.insert(0, 'T');
            }
            seq = seq >> 2;
        }
        return new String(sb);
    }
}

2015年6月12日星期五

[LeetCode] Maximal Square

Problem:

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 4.

Solution:

Dynamic Programming, explanation: 
http://bookshadow.com/weblog/2015/06/03/leetcode-maximal-square/

Java Code:

public class Solution {
    public int maximalSquare(char[][] matrix) {
        if (matrix == null || matrix.length == 0) {
            return 0;
        }
        
        int[][] dp = new int[matrix.length][matrix[0].length];
        int max = 0;
        
        for (int i = 0; i < matrix.length; i++) {
            dp[i][0] = matrix[i][0] == '1' ? 1 : 0;
            max = Math.max(max, dp[i][0]);
        }
        
        for (int j = 0; j < matrix[0].length; j++) {
            dp[0][j] = matrix[0][j] == '1' ? 1 : 0;
            max = Math.max(max, dp[0][j]);
        }
        
        
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                dp[i][j] = matrix[i][j] == '1' ? 
                Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1 : 0;
                max = Math.max(max, dp[i][j]);
            }
        }
        
        return (int)Math.pow(max, 2);
    }
}

[LeetCode] Count Complete Tree Nodes

Problem:

Given a complete binary tree, count the number of nodes.

Java Code:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        
        int leftHeight = countLeftHeight(root);
        int rightHeight = countRightHeight(root);
        if (leftHeight == rightHeight) {
            return (int)Math.pow(2, leftHeight + 1) - 1;//Attn: Mistake ^ operator as power here.
        } 
        
        return 1 + countNodes(root.left) + countNodes(root.right);
        
    }
    
    private int countLeftHeight(TreeNode root) {
        if (root == null) {
            return -1;
        }
        return 1 + countLeftHeight(root.left);
    }
    
    private int countRightHeight(TreeNode root) {
        if (root == null) {
            return -1;
        }
        return 1 + countRightHeight(root.right);
    }
}


[LeetCode] Implement Stack using Queues

Problem:

Implement the following operations of a stack using queues.
push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
empty() -- Return whether the stack is empty.

Java Code:

class MyStack {
    Queue<Integer> q1 = new LinkedList<Integer>();
    Queue<Integer> q2 = new LinkedList<Integer>();
    int size = 0;
    // Push element x onto stack.
    public void push(int x) {
        q1.add(x);
        size++;
    }

    // Removes the element on top of the stack.
    public void pop() {
        if (size == 0) {
            return;
        }
        int i = size;
        while (i != 1) {
            q2.add(q1.poll());
            i--;
        }
        size--;
        q1.poll();
        Queue<Integer> tempQ = q1;
        q1 = q2;
        q2 = tempQ;
        return;
    }

    // Get the top element.
    public int top() {
        if (size == 0) {
            return 0;
        }
        int i = size;
        while (i != 1) {
            q2.add(q1.poll());
            i--;
        }
        int tmp = q1.peek();
        q2.add(q1.poll());
        Queue<Integer> tempQ = q1;
        q1 = q2;
        q2 = tempQ;
        return tmp;
    }

    // Return whether the stack is empty.
    public boolean empty() {
        return (q1.peek() == null) && (q2.peek() == null);
    }
}