Friday, June 12, 2015

Minimum Size Subarray Sum

Q:
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead.
For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.

A:
two pointer


public class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        if(nums == null || nums.length==0)
            return 0;
        int p1 =0,p2= -1; // both are inclusive
        int minLen = Integer.MAX_VALUE;
        long sum = 0;
        while(p2<nums.length){
            if(sum < s){
                p2++;
                if(p2<nums.length)
                    sum += nums[p2];
            }else{
                minLen = Math.min(minLen, p2-p1+1);
                sum -= nums[p1++]; // do not need to check if p1<=p2, coz they s is positive
            }
        }
        return minLen==Integer.MAX_VALUE?0:minLen;
    }
}





Mistakes:
 这道题的2大错误在于。
1: 刚开始用了 以前的双层循环的解法。  虽然复杂的没有变,但是写起来复杂了。 不好
2: 核心错误:  一开始p2没有确定是inclusive的,因此,开始没有设p2= -1;



***********第二遍*********

public class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int res = Integer.MAX_VALUE, pre = -1, sum = 0;
        for(int i =0;i<nums.length;i++){
            sum+= nums[i];
            if(sum<s)
                continue;
            while( sum-nums[pre+1] >= s){
                pre++;
                sum -= nums[pre];
            }
            res = Math.min(i-pre,res);
            sum = sum - nums[++pre];
        }
        return res == Integer.MAX_VALUE? 0 : res;
    }
}
 



208. Implement Trie (Prefix Tree) --M

Implement a trie with insert, search, and startsWith methods.
Example:
Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // returns true
trie.search("app");     // returns false
trie.startsWith("app"); // returns true
trie.insert("app");   
trie.search("app");     // returns true
Note:
  • You may assume that all inputs are consist of lowercase letters a-z.
  • All inputs are guaranteed to be non-empty strings.

A:

不要搞得太复杂,就是每个character一个节点就行了了。(外加HashMap)
( empty String “”  是所有 字符串的前缀。~~~即使还没有开始存)

class Trie {
public:
    /** Initialize your data structure here. */
    Trie() {
        root = new Node();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Node *cur = root;
        for(int i =0;i<word.length();++i)
        {
            char ch = word[i];
            if(cur->chmap.find(ch) == cur->chmap.end())
            {
                Node* tmp = new Node();
                cur->chmap[ch] = tmp;
            }             
            cur = cur->chmap.at(ch);
        }
        cur->isLeaf = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Node *cur = root;        
        for(int i =0;i<word.length();++i)
        {
            char ch = word[i];
            if(cur->chmap.find(ch)==cur->chmap.end())
            {
                return false;
            }
            cur = cur->chmap.find(ch)->second;
        }
        return cur->isLeaf;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
                Node *cur = root;        
        for(int i =0;i<prefix.length();++i)
        {
            char ch = prefix[i];
            if(cur->chmap.find(ch)==cur->chmap.end())
            {
                return false;
            }
            cur = cur->chmap.find(ch)->second;
        }
        return true;
    }
private:
    struct Node{
        unordered_map<char,Node*> chmap;
        bool isLeaf=false;
    };
    Node * root; // root contains no char to reach it
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */



Mistakes:
1:  一开始加上了,如果该节点后面没有,就自己保存一个string,搞得太复杂
2: 这道题,最容易错的地方是,search和 startWith中,最后要检查是否是null节点。








Wednesday, June 10, 2015

207. Course Schedule ----M !!!

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

  • For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.

Return true if you can finish all courses. Otherwise, return false.

 

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take. 
To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

 

Constraints:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • All the pairs prerequisites[i] are unique.
A:
就是topological sort (CLIS上的经典代码)
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> Color(numCourses, 0); //0 for white, 1 for gray, and 2 for black
unordered_map<int, vector<int>> M;
for (auto pre : prerequisites) {
M[pre[0]].push_back(pre[1]);
}
for (int i = 0; i < numCourses; i++) {
if (not dfs(M, Color, i))
return false;
}
return true;
}

private:
bool dfs(unordered_map<int, vector<int>>& M, vector<int>& Color, int i) {
if (Color[i] == 2) {
return true;
}
if (Color[i] == 1) {
return false;
}
Color[i] = 1; // mark gray now,
for (int val : M[i]) {
auto res = dfs(M, Color, val);
if (not res)
return false;
}
Color[i] = 2;
return true;
}
};

-------------old---------每次traversal的同时,还可以在限制条件里  删去已经满足的class ----------
public class Solution {
        public boolean canFinish(int numCourses, int[][] prerequisites) {
        Set<Integer> set = new HashSet();
        Map<Integer, List<Integer>>  map = new HashMap();
        for(int i =0; i<numCourses; i++)  // initialize
            map.put(i,new LinkedList<Integer>());

        for(int j =0; j<prerequisites.length;j++)  // build the set
            map.get(prerequisites[j][0]).add(prerequisites[j][1]);

        boolean foundOne = true;
        while( !map.isEmpty() && foundOne){
            foundOne = false;
            for(int key : map.keySet()){
                boolean allTaken = true;
                List constrainList = map.get(key);
                for(int k = 0;k< constrainList.size();k++) // k is the constrain class
                    if( !set.contains(constrainList.get(k))){ // get the pre-requirement for class  key
                        allTaken = false;
                        break;
                    }else{ // this constrain class (k) is already found
                        constrainList.remove(k); // delete this constrains
                        k--;
                    }
                if(allTaken){
                    foundOne = true;
                    set.add(key);
                    map.remove(key);
                    break;
                }
            }
        }
        return map.isEmpty();
    }
}
 
注意,这里,最后一个break没有加的时候,仍然会超时。


Mistakes:
 1:  当 input 为1 [] 的时候, 陷入了死循环。    原因在于忘记找到可以先上的课后,把它放到set里的同时, 还要 map.remove()了

2:   第一遍解法的时候,如果 最后一个break没有加的时候,仍然会超时。   按理说不应该呀???




Saturday, May 9, 2015

206. Reverse Linked List (easy). !!

Q:

Given the head of a singly linked list, reverse the list, and return the reversed list.

 

Example 1:

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

Example 2:

Input: head = [1,2]
Output: [2,1]

Example 3:

Input: head = []
Output: []

 

Constraints:

  • The number of nodes in the list is the range [0, 5000].
  • -5000 <= Node.val <= 5000


Follow up:
 A linked list can be reversed either iteratively or recursively. Could you implement both?

A:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
用dummy header
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode header;
while (head) {
auto tmp = head;
head = head->next;
tmp->next = header.next;
header.next = tmp;
}
return header.next;
}
};



或者把 新的head,不用 dummy header, 而是指向最新的head. 只是尽量晚赋值
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* newHead = nullptr;
while (head) {
ListNode* nextNode = head->next;
head->next = newHead;
newHead = head;
head = nextNode;
}
return newHead;
}
};


**********Mistakes*************

ListNode *header(0);  ---------> this grammar is WRONG. 

It initializes header as a null pointer (nullptr) because:

  • header is a pointer (ListNode*).
  • 0 is an integer literal, which implicitly converts to nullptr in C++ when assigned to a pointer.
Thus header is equivalent to
ListNode* header = nullptr; // Explicitly setting it to nullptr

This means header->next is an invalid operation because header is nullptr.



Correct Way to Create a Dummy Node

If you meant to create an actual ListNode object, you should write:

ListNode dummy(0); // Correct: Creates an actual ListNode
or use dynamic allocation:
      ListNode* header = new ListNode(0); // Allocates a real ListNode on the heap



Tuesday, May 5, 2015

Addictive Number

Q:
Problem (Epic): Additive numbers are defined to be a positive integer whose digits form an additive sequence. E.g. 11235 (1+1=2, 1+2=3, 2+3=5). What makes it difficult is that 12,122,436 is also one (12+12=24, 12+24=36). Given a range of integers, find all the additive numbers in that range..


A:
自己的思路是先确定是几位的数字,例如从 1 到99999,我们就分别设置数组长为1 到5.

然后对那么长的数组,分别求addative number. 再检查是否within range 



XXX number  -------- sorry (I forget the name ):
find all XXX number within range [low high]
XXX number is defined as :
  each adjacent position will differ only 1.   for example 8798 is a XXX number,  890 is NOT.

permutaion II

Given a string, print all its permutations, (only lower case character can be permuted)


Contagious patient
就是一个party,互相握手。 有一个人开始有传染病。 最终多少人会有传染病?
输入是一个数值, 和一个2D array.

Saturday, May 2, 2015

Digit Counts

Q:
Count the number of k's between 0 and n. k can be 0 - 9.
Example
if n=12, in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], we have FIVE 1's (1, 10, 11, 12)

A:



Friday, May 1, 2015

205. Isomorphic Strings -E

Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
Example 1:
Input: s = "egg", t = "add"
Output: true
Example 2:
Input: s = "foo", t = "bar"
Output: false
Example 3:
Input: s = "paper", t = "title"
Output: true
Note:
You may assume both s and t have the same length.
A:
就是两个一一映射的关系。
用2个mapping就行了

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        return helper(s,t) && helper(t,s);
    }
private:
    bool helper(string s, string t)
    {
        map<char, char> mymap;
        for(int i =0;i<s.length();++i)
        {
            char ch1 = s[i];
            char ch2 = t[i];
            if(mymap.find(ch1)==mymap.end()) // first time find
            {
                mymap.insert({ch1,ch2});
            }else{
                if(mymap.find(ch1)->second != ch2)
                {
                    return false;
                }
            }
        }
        return true;
    }
};


通常的做法就是用2个map,这样就不用call 2 遍。

还有就是不用map, 直接用array, 用char 的值做index.