Tuesday, April 9, 2013

Day 13, 24, 35 Swap Nodes in Pairs, Search Insert Position

Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
--------
Solution #1
pre has the address of "next" of the previous node
pre can be replace by a ListNode* type.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        ListNode *saved;
        ListNode **pre;
        if (head != NULL && head->next != NULL) {
            saved = head->next;
            pre = &(head->next);
        }else {
            return head;
        }
        while (head != NULL && head->next != NULL) {
            *pre = head->next;
            ListNode *temp = head->next->next;
            head->next->next = head;
            head->next = temp;
            pre = &(head->next);
            head = temp;
            
        }
        return saved;
    }
};

Update on Sep-03-2014 
Solution #2, with dummy node
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
        ListNode *dummy;
        dummy->next = head;
        ListNode *itr = dummy;
        
        while (head != NULL && head->next != NULL) {
                itr->next = head->next;
                ListNode *temp = head->next->next;
                head->next = temp;
                itr->next->next = head;
                itr = head;
                head = temp;
        }
        
        return dummy->next;
    }
};

Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
 -----------------------------------
 For #2, #3, if match is not found, compare target with A[start] to determine the final position

Solution #1 O(n) 
class Solution {
public:
    int searchInsert(int A[], int n, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        
        for(int i=0;i<n;i++) {
            if (A[i] >= target) {
                return i;
            }
        }
        return n;
        
    }
};
Solution #2 O(log n), recursive
class Solution {
public:
    int rec (int A[], int start, int end, int target) {
        
        if (start >= end) {
            if (A[start] >= target) {
                return start;
            }
            return start+1;
        }
        int mid = (start + end) / 2;
        if (A[mid] == target) {
            return mid;
        }
        if (A[mid] < target) {
            return rec(A,mid+1,end,target);
        }else {
            return rec(A,start,mid-1,target);
        }
    }
    int searchInsert(int A[], int n, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        
        return rec(A,0,n-1,target);
    }
};
Solution #3 O(log n)
class Solution {
public:
    int searchInsert(int A[], int n, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int start = 0, end = n-1;
        
        while (start < end) {
            int mid = (start + end) / 2;
            if (A[mid] == target) {
                return mid;
            }
            if (A[mid] < target) {
                start = mid + 1;
            }else {
                end = mid - 1;
            }
        }
        if (A[start] >= target) {
            return start;
        }else {
            return start+1;
        }
    }
};
another version
class Solution {
public:
    int searchInsert(int A[], int n, int target) {
        int mid = n / 2;
        int left = 0, right = n - 1;
        
        while (left <= right) {
            mid = (left + right) / 2;
            if (A[mid] == target) {
                return mid;
            }
            if (A[mid] > target) {
                right = mid - 1;
            }else {
                left = mid + 1;
            }
        }
        
        return right + 1;
    }
};

Monday, April 8, 2013

Day 12, 21 Merge Two Sorted Lists

Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
 ---------------------------------
Solution #1
handle 2 special cases at the beginning,
1) either l1 or l2 is NULL, or both are NULL
2) either l1 or l2 has only one element, or both have only one element

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (l1 == NULL) {
            return l2;
        }
        if (l2 == NULL) {
            return l1;
        }
        
        ListNode *saved, *pre;
        if (l1->val < l2->val) {
            saved = l1;
            pre = l1;
            l1 = l1->next;
            pre->next = l2;
        }else {
            saved = l2;
            pre = l2;
            l2 = l2->next;
            pre->next = l1;
        }
        
        while (l1 != NULL && l2 != NULL) {
            if (l1->val < l2->val) {
                pre->next = l1;
                pre = l1;
                l1 = l1->next;
                pre->next = l2;
            }else {
                pre->next = l2;
                pre = l2;
                l2 = l2->next;
                pre->next = l1;
            }
        }
        return saved;
    }
};

Solution #2
recursion
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (l1 == NULL) {
            return l2;
        }
        if (l2 == NULL) {
            return l1;
        }
        ListNode *re;
        if (l1->val < l2->val) {
            re = l1;
            re->next = mergeTwoLists(l1->next,l2);
        }else {
            re = l2;
            re->next = mergeTwoLists(l1,l2->next);
        }
        return re;
    }
};

Solution #3, from others
cur saves the address of the "next" in last node
class Solution {  
public:  
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {  
        ListNode* ret = NULL;  
        ListNode** cur = &ret;  
        while(NULL != l1 && NULL != l2)  
        {  
            if(l1->val < l2->val)  
            {  
                *cur = l1;  
                cur = &(l1->next);  
                l1 = l1->next;  
            }  
            else  
            {  
                *cur = l2;  
                cur = &(l2->next);  
                l2 = l2->next;  
            }  
        }  
        *cur = NULL == l1? l2: l1;  
        return ret;  
    }  
};  

update
Solution #4, using dummy head
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        ListNode* dummy = new ListNode(0);
        ListNode* itr = dummy;
        while (l1 != NULL && l2 != NULL) {
            if (l1->val < l2->val) {
                itr->next = l1;
                itr = l1;
                l1 = l1->next;
            }else {
                itr->next = l2;
                itr = l2;
                l2 = l2->next;
            }
        }
        if (l1 == NULL) {
            itr->next = l2;
        }else {
            itr->next = l1;
        }
        return dummy->next;
    }
};

Friday, April 5, 2013

Day 11, 14,19,20, Longest Common Prefix, Remove Nth Node From End of List, Valid Parentheses

Longest Common Prefix
Write a function to find the longest common prefix string amongst an array of strings.  
---------
 grab the first string in array, compare its i-th element to other strings' i-th element

Is there a better solution?
 
class Solution {
public:
    string longestCommonPrefix(vector<string> &strs) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (strs.size() == 0) {
            return "";
        }
        bool flag = false; // to break the outer for loop
        string prefix = "";
        for (int i=0;i<strs[0].length();i++) {
            for (int j=1;j<strs.size();j++) {
                if (strs[j] == "" || strs[0][i] != strs[j][i]) {
                    // to break the outer for loop
                    flag = true;
                    break;
                }
            }
            
            if (flag) break;
            prefix = prefix + strs[0][i];
        }
        return prefix; 
    }
}; 
Added on Sep-02-2014
Instead of using first string, use 26 alphabet letters to check each string

Remove Nth Node From End of List
Given a linked list, remove the nth node from the end of list and return its head.
For example,
   Given linked list: 1->2->3->4->5, and n = 2.

   After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
----------
two pointers
 
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *pre = new ListNode(0), *dummy = pre;
        pre->next = head;
        int k = 0;
        while (head != NULL) {
            head = head->next;
            k++;
        }
        k = k - n;
        while (k > 0) {
            k--;
            pre = pre->next;
        }
    
        pre->next = pre->next->next;
        return dummy->next;
    }
};
Valid Parentheses
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
---------------------
use a stack 
class Solution {
public:
    bool isValid(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        stack<char> st;
        for (int i=0;i<s.length();i++) {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{') {
                st.push(s[i]);
            }else {
                if (st.empty()) {
                    return false;
                }
                char c = st.top();
                st.pop();
                if ((s[i] == ')' && c == '(') || (s[i] == '}' && c == '{') || (s[i] == ']' && c == '[')) {
                    ;
                }else return false;
            }
        }
        if (st.empty()) {
            return true;
        }
        return false;
    }
};

Thursday, April 4, 2013

Day 10, 13 Roman to Integer

Roman to Integer
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
---------------------------
first, setup a dictionary, then walk through the whole string
according to the Roman numeral rule, if str[i] < str[i+1], then str[i] should be negative
watch out for the end element of the string, it could be compared to an unknown  value.
 
class Solution {
public:
    int romanToInt(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        unordered_map<char,int> k;
        k['I'] = 1;
        k['V'] = 5;
        k['X'] = 10;
        k['L'] = 50;
        k['C'] = 100;
        k['D'] = 500;
        k['M'] = 1000;
        int sum=0;
        for (int i=0;i<s.length();i++) {
            int sign = 1;
            if (k[s[i]] < k[s[i+1]]) {
                sign = -1;  
            }
            sum = sum + k[s[i]] * sign;
        }
        return sum;
    }
};
Added on Sep-02-2014
Handled final char in string
class Solution {
public:
    unordered_map<char,int> populateMap() {
        unordered_map<char,int> dic;
        dic['I'] = 1;
        dic['V'] = 5;
        dic['X'] = 10;
        dic['L'] = 50;
        dic['C'] = 100;
        dic['D'] = 500;
        dic['M'] = 1000;
        dic['e'] = 0;
        
        return dic;
    }

    int romanToInt(string s) {
        unordered_map<char,int> dic = populateMap();
        int ret = 0;
        s += 'e';
        
        for (int i = 0; i < s.length(); i++) {
            if (dic[s[i]] < dic[s[i + 1]]) {
                ret += dic[s[i + 1]] - dic[s[i]]; 
                i++;
            }else {
                ret += dic[s[i]];
            }    
        }
        return ret;
    }
};

Wednesday, April 3, 2013

Day 9, 9 Palindrome Number

Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.
Some hints: Could negative integers be palindromes? (ie, -1)
If you are thinking of converting the integer to string, note the restriction of using extra space.
You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?
There is a more generic way of solving this problem.

 
class Solution {
public:
    bool isPalindrome(int x) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (x < 0) { 
            return false;
        }
        
        // reverse
        int temp = x;
        int y = 0;
        while (temp>0) { 
            y = 10 * y + temp % 10;
            temp = temp / 10;
        }
        
        if (x != y) {
            return false;
        }
        return true;
    }
};




Tuesday, April 2, 2013

Day 8, 8 String to Integer (atoi)

 String to Integer (atoi)

Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
Requirements for atoi: The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.
If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

Solution #1
class Solution {
public:
    int myAtoi(string str) {
        int rt = 0,i = 0;
        int sign = 1;
        while (isspace(str[i])) {
            i++;
        }
        if (str[i] == '-') {
            i++;
            sign = -1;
        }else if (str[i] == '+') i++;
        
        while (i < str.length() && isdigit(str[i])) {
            if (sign == 1 && (rt > 214748364 || (rt == 214748364 && str[i] - '0' > 7))) {
                return INT_MAX;
            }
            if (sign == -1 && (rt > 214748364 || (rt == 214748364 && str[i] - '0' > 8))) {
                return INT_MIN;
            }
            rt = rt * 10 + str[i] - '0';
            i++;
        }
        
        return rt * sign;
    }
};
Solution #2
declare result as long long type;
class Solution {
 public:
  int atoi(const char *str) {
    long long r = 0;
    int i = 0;
    bool negtive = false;
    while(str[i] == ' ')i++;
    if(str[i] == '+') i++;
    else if (str[i] == '-') {
      negtive = true;
      i++;
    }
    for(; str[i] >= '0' && str[i] <= '9'; i++) {
      int d = str[i] - '0';
      if(negtive)r = 10*r - d;
      else r = 10*r + d;
      if( r > numeric_limits<int>::max()) return numeric_limits<int>::max();
      if( r < numeric_limits<int>::min()) return numeric_limits<int>::min();
    }
    return r;
  }

Day 7, 7 Reverse Integer

Reverse Integer
Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321
Have you thought about this?

Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!

If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100.

Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?

Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter).

Solution #1
class Solution {
public:
    int reverse(int x) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        bool minus = false;
        if (x < 0) {
            x = -x;
            minus = true;
        }
        
        int rev=0;
        while (x > 0) {
            rev = rev * 10 + x%10;
            x = x/10;
        }
        
        if (minus) {
            return -1 * rev;
        }
        return rev;
        
    }
};
检测溢出
class Solution {
public:
    int reverse(int x) {
        int rt = 0,temp = x;
        int sign = 1;
        if (x < 0) {
            sign = -1;
            temp = abs(x);
        }
        
        while (temp > 0) {
            if (rt > INT_MAX / 10 || (rt == INT_MAX / 10 && temp % 10 > 7)) return 0;
            rt = rt * 10 + temp % 10;
            temp /= 10; 
        }
        return rt * sign;
    }
};