Friday, April 26, 2013

Search in Rotated Sorted Array


Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.


解题思路:
binary search的变型



public class SearchInRotatedArray {
    public int search(int[] A, int target) {
        int start = 0, end = A.length - 1;
        
        while(start <= end){
            int mid = start + (end - start)/2;
            
            if(A[mid] == target){
                return mid;
            }
            
            if(A[start] <= A[mid]){
                if(target < A[start] || target > A[mid]){
                    start = mid + 1;
                }
                else{
                    end = mid - 1;
                }
            }
            else{
                if(target > A[mid] && target < A[start]){
                    start = mid + 1;
                }
                else{
                    end = mid - 1;
                }
            }
        }
        
        return -1;
    }
}

Saturday, April 20, 2013

Integer to Roman

Given an integer, convert it to a roman numeral.


Roman Numerals, as used today, are based on seven symbols:[1]
SymbolValue
I1
V5
X10
L50
C100
D500
M1,000


[解题思路]
按照区间处理digit:
digit <=3
digit =4
5<=digit<=8
digit =9

code:

public class IntegerToRoman {
    public String intToRoman(int num) {
        StringBuffer buffer = new StringBuffer();
        char[] roman = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
        int divide = 1000;
        
        for(int i = 0; i <= 3; i++){
            int d = num / divide;
            num %= divide;
            
            if(d <= 3){
                append(buffer, roman, i*2, d);
            }
            else if(d == 4){
                append(buffer, roman, i*2, 1);
                append(buffer, roman, i*2-1, 1);
            }
            else if(d <= 8){
                append(buffer, roman, i*2-1, 1);
                append(buffer, roman, i*2, d - 5);
            }
            else{
                append(buffer, roman, i*2, 1);
                append(buffer, roman, (i - 1)*2, 1);
            }
            divide /= 10;
        }
        return new String(buffer);
    }
    
    public void append(StringBuffer buffer, char[] roman, int i, int d){
        for(int j = 0; j < d; j++){
            buffer.append(roman[i]);
        }
    }
}

Thursday, April 18, 2013

Container With Most Water


Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
[解题思路]
双指针的变型,可以实现O(n),别的没什么好说的。
code:
public class ContainerWithMostWater {
    
    public int maxArea(int[] height) {
        int size = height.length;
        if(size == 0){
            return -1;
        }
        
        int i = 0, j = size - 1, v = 0;
        while(i < j){
            int temp = (j - i) * Math.min(height[i], height[j]);
            v = Math.max(v, temp);
            
            if(height[i] < height[j]){
                i++;
            }
            
            else if(height[i] > height[j]){
                j--;
            }
            
            else{
                i++;
                j--;
            }
        }
        return v;
    }
}


Wednesday, April 17, 2013

Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") ? false
isMatch("aa","aa") ? true
isMatch("aaa","aa") ? false
isMatch("aa", "a*") ? true
isMatch("aa", ".*") ? true
isMatch("ab", ".*") ? true
isMatch("aab", "c*a*b") ? true
public class Solution {     public boolean isMatch(String s, String p) {         return func(s, p, s.length() - 1, p.length() - 1);     }          public boolean func(String s, String p, int i1, int i2){         if(i1 == -1 && i2 == -1){             return true;         }         else if(((i1 < 0 && p.charAt(i2)!='*') || i2 < 0)){             return false;         }                          if(p.charAt(i2) == '.'){             return func(s, p, i1 - 1, i2 -1);         }         else if(p.charAt(i2) == '*'){             i2--;             while(true){                 if(func(s, p, i1, i2 - 1)){                     return true;                 }                 if(i1 < 0 || (s.charAt(i1) != p.charAt(i2) && p.charAt(i2) != '.')){                     break;                 }                 i1--;             }         }         else{             return (s.charAt(i1) == p.charAt(i2)) && func(s, p, i1-1, i2-1);         }                  return false;     }
}

Tuesday, April 16, 2013

Add Two Numbers


You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
code:
public class add2Numbers {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode iter1 = l1, iter2 = l2, newList = new ListNode(0), tail = newList;
        int carry = 0, sum;
        
        while(iter1 != null || iter2 != null){
            sum = carry;
            
            if(iter1 != null){
                sum += iter1.val;
                iter1 = iter1. next;
            }
            
            if(iter2 != null){
                sum += iter2.val;
                iter2 = iter2.next;
            }
            
            carry = sum / 10;
            sum %= 10;
            
            tail.next = new ListNode(sum);
            tail = tail.next;
        }
        
        if(carry != 0){
            tail.next = new ListNode(carry);
        }
        
        return newList.next;
    }
}

Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.


two pointer构建sliding window 初始化为 [0, 0]. Increasing right side from 0  to length - 1. 如果新加的char已存在于现窗口中,则update longest length,同时adjust left side。
improvement: 用int[26]数组储存char出现的位置, update left side 为table里面当前duplicate char的位置+1。

Code:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        // Start typing your Java solution below
        // DO NOT write main() function
        int i = 0, j, longestLength = 0;
        int[] flag = new int[26];
        
        for(j = 0; j < s.length(); j++){
            int index = s.charAt(j) - 'a';
            // duplicate char
            if(flag[index] != 0){
                longestLength = Math.max(j-i, longestLength);
                // adjust left side of window
                while(i < flag[index]){
                    flag[s.charAt(i) - 'a'] = 0;
                    i++;
                }
            }
            flag[index] = j + 1;
        }
        longestLength = Math.max(j-i, longestLength);
        return longestLength;
    }
}


Two Sum


Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
这道题还蛮经典的,遇见好多次,还有很多变型,例如more than one solution, return all the pairs.
1. brute force. O(n2)
2. sort then apply two pointer algorithm. O(nlogn) + O(n)
3. hashtable, time complexity O(n), space complexity O(n)
code:

public class Solution {
    public int[] twoSum(int[] numbers, int target) {
        // Start typing your Java solution below
        // DO NOT write main() function
        HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
        int[] result = {-1, -1};
        
        for(int i = 0; i < numbers.length; i++){
            // if target - numbers[i] exists in table
            int pair = target - numbers[i];
            if(table.containsKey(pair)){
                result[0] = table.get(pair) + 1;
                result[1] = i + 1;
                return result;
            }
            else{
                table.put(numbers[i], i);
            }
        }
        return result;
    }
}