Friday, April 29, 2016

LeetCode Q299: Bulls and Cows

You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number.
For example:
Secret number:  "1807"
Friend's guess: "7810"
Hint: 1 bull and 3 cows. (The bull is 8, the cows are 01 and 7.)
Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B".
Please note that both secret number and friend's guess may contain duplicate digits, for example:
Secret number:  "1123"
Friend's guess: "0111"
In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B".
You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

Solution:

class Solution {
public:
string getHint(string secret, string guess) {
int map[10];
for(int i=0; i<10; i++) map[i]=0;
for(int i=0; i<secret.length(); i++)
map[secret[i]-'0']++;
int bull = 0;
int cow = 0;
for(int i=0; i<guess.length(); i++){
if(guess[i]==secret[i]){
bull++;
map[guess[i]-'0']--;
guess[i]='#';
}
}
for(int i=0; i<guess.length(); i++){
if(map[guess[i]-'0']!=0&&guess[i]!='#'){
cow++;
map[guess[i]-'0']--;
}
}
string res = to_string(bull)+string("A")+to_string(cow)+string("B");
return res;
}
};
view raw Q299.cpp hosted with ❤ by GitHub

LeetCode Q298: Binary Tree Longest Consecutive Sequence

Given a binary tree, find the length of the longest consecutive sequence path.
The path refers to any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The longest consecutive path need to be from parent to child (cannot be the reverse).
For example,
   1
    \
     3
    / \
   2   4
        \
         5
Longest consecutive sequence path is 3-4-5, so return 3.
   2
    \
     3
    / 
   2    
  / 
 1
Longest consecutive sequence path is 2-3,not3-2-1, so return 2.

Solution:

/**
* 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:
void helper(TreeNode* node, int lastVal, int curLen, int& maxLen){
if(node==NULL)
return;
if(node->val == lastVal+1){
maxLen = max(maxLen, curLen+1);
}else
curLen = 0;
helper(node->left, node->val, curLen+1, maxLen);
helper(node->right, node->val, curLen+1, maxLen);
}
int longestConsecutive(TreeNode* root) {
if(!root)
return 0;
int maxLen = 1;
helper(root->left, root->val, 1, maxLen);
helper(root->right, root->val, 1, maxLen);
return maxLen;
}
};
view raw Q298.cpp hosted with ❤ by GitHub

LeetCode Q297: Serialize and Deserialize Binary Tree (hard)

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
For example, you may serialize the following tree
    1
   / \
  2   3
     / \
    4   5
as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

Solution:

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
string serialize(TreeNode* root) {
string res;
queue<TreeNode*> myQ;
if(root==NULL)
return res;
myQ.push(root);
while(!myQ.empty()){
TreeNode* node = myQ.front();
myQ.pop();
if(node==NULL){
res = res + string(" ") + string("#");
continue;
}
myQ.push(node->left);
myQ.push(node->right);
res = res.length()==0? to_string(node->val) : res + string(" ") + to_string(node->val);
}
return res;
}
void split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if(data.length()==0)
return NULL;
vector<string> elems;
split(data, ' ', elems);
int p=0;
queue<TreeNode*> myQ;
TreeNode* root = new TreeNode(stoi(elems[p]));
myQ.push(root);
p++;
while(!myQ.empty()){
TreeNode* node = myQ.front();
myQ.pop();
string sl = elems[p++];
string sr = elems[p++];
if(sl!=string("#")){
TreeNode* nl = new TreeNode(stoi(sl));
node->left = nl;
myQ.push(nl);
}
if(sr!=string("#")){
TreeNode* nr = new TreeNode(stoi(sr));
node->right = nr;
myQ.push(nr);
}
}
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
view raw Q297.cpp hosted with ❤ by GitHub

LeetCode Q296: Best Meeting Point (hard)

 A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.
For example, given three people living at (0,0)(0,4), and (2,2):
1 - 0 - 0 - 0 - 1
|   |   |   |   |
0 - 0 - 0 - 0 - 0
|   |   |   |   |
0 - 0 - 1 - 0 - 0
The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6.

Solution:

class Solution {
public:
int minTotalDistance(vector<vector<int>>& grid) {
if(grid.size()==0)
return 0;
int rows = grid.size();
int cols = grid[0].size();
vector<int> X(cols);
vector<int> Y(rows);
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
if(grid[i][j]==0)
continue;
int x = j;
int y= i;
for(int k=0; k<cols; k++)
X[k]=X[k]+abs(x--);
for(int k=0; k<rows; k++)
Y[k]=Y[k]+abs(y--);
}
}
int minv = INT_MAX;
for(int i=0; i<rows; i++)
for(int j=0; j<cols; j++)
minv = min(minv, X[j]+Y[i]);
return minv;
}
};
view raw Q296.cpp hosted with ❤ by GitHub

Thursday, April 28, 2016

LeetCode Q295: Find Median from Data Stream (hard)

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples: 
[2,3,4] , the median is 3
[2,3], the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
  • void addNum(int num) - Add a integer number from the data stream to the data structure.
  • double findMedian() - Return the median of all elements so far.
For example:
add(1)
add(2)
findMedian() -> 1.5
add(3) 
findMedian() -> 2

Solution:
Keep two heaps, one storing smaller half of data, another one store larger half of the data. The size of smaller one is greater or equal to the larger one.

class MedianFinder {
public:
priority_queue<long> small, large;
// Adds a number into the data structure.
void addNum(int num) {
small.push(num);
large.push(-small.top());
small.pop();
if (small.size() < large.size()) {
small.push(-large.top());
large.pop();
}
}
// Returns the median of current data stream
double findMedian() {
return small.size()>large.size()? small.top():(small.top()-large.top())/2.0;
}
};
// Your MedianFinder object will be instantiated and called as such:
// MedianFinder mf;
// mf.addNum(1);
// mf.findMedian();
view raw Q295.cpp hosted with ❤ by GitHub

LeetCode Q294: Flip Game II

You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive"++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.
Write a function to determine if the starting player can guarantee a win.
For example, given s = "++++", return true. The starting player can guarantee a win by flipping the middle "++" to become "+--+".
Follow up:
Derive your algorithm's runtime complexity.
Solution:
Using backtracking. In each new call to the function, we only consider whether current player can win by flipping two signs in current configuration. Then we return the result to the last function call. Don't confusing yourself by setting up the order of the players.

bool canWin(string s) {
if (s.size() == 0) {
return false;
}
bool isMoved = false;
for (size_t i = 0; i < s.size() - 1; ++i) {
if (s[i] == '+' && s[i + 1] == '+') {
isMoved = true;
s[i] = '-';
s[i + 1] = '-';
if (!canWin(s)) {
return true;
}
s[i] = '+';
s[i + 1] = '+';
}
}
if (!isMoved) {
return false;
}
}
view raw Q294.cpp hosted with ❤ by GitHub

LeetCode Q291: Word Pattern II (hard)

Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty substring in str.
Examples:
  1. pattern = "abab", str = "redblueredblue" should return true.
  2. pattern = "aaaa", str = "asdasdasdasd" should return true.
  3. pattern = "aabb", str = "xyzabcxzyabc" should return false.
Notes:
You may assume both pattern and str contains only lowercase letters.

Solution:
Use DFS with recursion. The difficulty is to distinguish each situation during search.

class Solution {
public:
bool helper(string pat, string str, int patLoc, int strLoc,
unordered_map<char, string>& map0,
unordered_map<string, char>& map1){
if(patLoc==pat.length()&&strLoc==str.length())
return true;
bool res=false;
char patChar = pat[patLoc];
for(int j=1; j<=str.length()-strLoc; j++){
string subStr = str.substr(strLoc, j);
auto it0 = map0.find(patChar);
auto it1 = map1.find(subStr);
if(it0==map0.end()&&it1==map1.end()){
map0[patChar]=subStr;
map1[subStr]=patChar;
res = helper(pat, str, patLoc+1, strLoc+j, map0, map1);
if(res)
return true;
else{
map0.erase(patChar);
map1.erase(subStr);
}
continue;
}
if(it0!=map0.end()&&it1!=map1.end()){
if(it0->first==it1->second&&it0->second==it1->first){
res = helper(pat, str, patLoc+1, strLoc+j, map0, map1);
if(res)
return true;
else
return false;
}
}
else{
if(it0==map0.end()||it1==map1.end())
continue;
if(it0!=map0.end()&&subStr.length()>(it0->second).length())
return false;
continue;
}
}
return false;
}
bool wordPatternMatch(string pattern, string str) {
unordered_map<char, string> map0;
unordered_map<string, char> map1;
bool res = helper(pattern, str, 0, 0, map0, map1);
return res;
}
};
view raw Q291.cpp hosted with ❤ by GitHub

Wednesday, April 27, 2016

LeetCode Q293: Flip Game

You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive"++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner.
Write a function to compute all possible states of the string after one valid move.
For example, given s = "++++", after one move, it may become one of the following states:
[
  "--++",
  "+--+",
  "++--"
]
If there is no valid move, return an empty list [].
Solution:

class Solution {
public:
vector<string> generatePossibleNextMoves(string s) {
vector<string> res;
if(s.length()<=1)
return res;
for(int i = 0; i<s.length()-1; i++){
if(s[i]==s[i+1]&&s[i]=='+'){
string tmp = s;
tmp[i] = tmp[i]=='+'? '-':'+';
tmp[i+1] = tmp[i];
res.push_back(tmp);
}
}
return res;
}
};
view raw Q293.cpp hosted with ❤ by GitHub

LeetCode Q292: Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.
Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.
For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.
Hint:
  1. If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner?
Solution:
To get the last one, I have to get the 4th one from the last, to make sure I win, I have to guarantee that I can always grab the number which is not multiple of 4. So this question turns out to be the one which require you determine whether the number is multiple of 4.

class Solution {
public:
bool canWinNim(int n) {
return !(n%4==0);
}
};
view raw Q292.cpp hosted with ❤ by GitHub

LeetCode Q290: Word Pattern

Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.
Examples:
  1. pattern = "abba", str = "dog cat cat dog" should return true.
  2. pattern = "abba", str = "dog cat cat fish" should return false.
  3. pattern = "aaaa", str = "dog cat cat dog" should return false.
  4. pattern = "abba", str = "dog dog dog dog" should return false.
Notes:
You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

Solution:

class Solution {
public:
bool wordPattern(string pattern, string str) {
unordered_map<char, string> myMap0;
unordered_map<string, char> myMap1;
vector<string> subStrs;
string _str;
for(int i=0; i<str.length(); i++){
if(str[i]==' '&&_str.length()!=0){
subStrs.push_back(_str);
_str=string("");
}
if(str[i]!=' ')
_str=_str+string(1, str[i]);
}
if(str.length()!=0)
subStrs.push_back(_str);
if(pattern.length()!=subStrs.size())
return false;
for(int i=0; i<pattern.length(); i++){
auto it0 = myMap0.find(pattern[i]);
auto it1 = myMap1.find(subStrs[i]);
if(it0==myMap0.end()&&it1==myMap1.end()){
myMap0[pattern[i]]=subStrs[i];
myMap1[subStrs[i]]=pattern[i];
}else{
if(it0!=myMap0.end()&&it1!=myMap1.end())
if(it0->first==it1->second||it0->second==it1->first)
continue;
else
return false;
else
return false;
}
}
return true;
}
};
view raw Q290.cpp hosted with ❤ by GitHub

LeetCode Q289: Game of Life

According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."
Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):
  1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by over-population..
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
Write a function to compute the next state (after one update) of the board given its current state.
Follow up
  1. Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
  2. In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?
Solution:
Since each entry use an int to store its two status which only cost 1 bit. We can use 2 bits to store old and new status. When finish all updates, shift number to right by 1 position to get new state.


class Solution {
public:
void gameOfLife(vector<vector<int>>& board) {
if(board.empty())
return;
int row = board.size();
int col = board[0].size();
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
int cell = board[i][j];
int liveCount=0;
for(int p = i-1; p<=i+1; p++)
for(int q=j-1; q<=j+1; q++){
if(p<0||p>=row||q<0||q>=col||(p==i&&q==j))
continue;
liveCount = (board[p][q]&1)==1? liveCount+1:liveCount;
}
if(cell==1){
if(liveCount==2||liveCount==3)
board[i][j]=3;
}else
if(liveCount==3)
board[i][j]=2;
}
}
for(int i=0; i<row; i++)
for(int j=0; j<col; j++)
board[i][j]=board[i][j]>>1;
}
};
view raw Q289.cpp hosted with ❤ by GitHub

Tuesday, April 26, 2016

LeetCode Q288: Unique Word Abbreviation

a) it                      --> it    (no abbreviation)

     1
b) d|o|g                   --> d1g

              1    1  1
     1---5----0----5--8
c) i|nternationalizatio|n  --> i18n

              1
     1---5----0
d) l|ocalizatio|n          --> l10n
Assume you have a dictionary and given a word, find whether its abbreviation is unique in the dictionary. A word's abbreviation is unique if no other word from the dictionary has the same abbreviation.
Example: 
Given dictionary = [ "deer", "door", "cake", "card" ]

isUnique("dear") -> false
isUnique("cart") -> true
isUnique("cane") -> false
isUnique("make") -> true
class ValidWordAbbr {
public:
ValidWordAbbr(vector<string> &dictionary) {
for (string& d : dictionary) {
int n = d.length();
string abbr = d[0] + to_string(n) + d[n - 1];
mp[abbr].insert(d);
}
}
bool isUnique(string word) {
int n = word.length();
string abbr = word[0] + to_string(n) + word[n - 1];
return mp[abbr].count(word) == mp[abbr].size();
}
private:
unordered_map<string, unordered_set<string>> mp;
};
// Your ValidWordAbbr object will be instantiated and called as such:
// ValidWordAbbr vwa(dictionary);
// vwa.isUnique("hello");
// vwa.isUnique("anotherWord");
view raw Q288.cpp hosted with ❤ by GitHub

LeetCode Q287: Find the Duplicate Number (hard)

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.
Solution 1;
The main idea is the same with problem Linked List Cycle II,https://leetcode.com/problems/linked-list-cycle-ii/. Use two pointers the fast and the slow. The fast one goes forward two steps each time, while the slow one goes only step each time. They must meet the same item when slow==fast. In fact, they meet in a circle, the duplicate number must be the entry point of the circle when visiting the array from nums[0]. Next we just need to find the entry point. We use a point(we can use the fast one before) to visit form begining with one step each time, do the same job to slow. When fast==slow, they meet at the entry point of the circle. The easy understood code is as follows.

class Solution {
public:
int findDuplicate(vector<int>& nums) {
if(nums.size()<1)
return -1;
int slow = nums[0];
int fast = nums[nums[0]];
while(slow!=fast){
slow=nums[slow];
fast=nums[nums[fast]];
}
fast = 0;
while(fast!=slow){
fast = nums[fast];
slow = nums[slow];
}
return slow;
}
};
view raw Q287.cpp hosted with ❤ by GitHub

Solution 2: This solution is based on binary search. At first the search space is numbers between 1 to n. Each time I select a number mid (which is the one in the middle) and count all the numbers equal to or less than mid. Then if the count is more than mid, the search space will be [1 mid] otherwise [mid+1 n]. I do this until search space is only one number. Let's say n=10 and I select mid=5. Then I count all the numbers in the array which are less than equal mid. If the there are more than 5 numbers that are less than 5, then by Pigeonhole Principle (https://en.wikipedia.org/wiki/Pigeonhole_principle) one of them has occurred more than once. So I shrink the search space from [1 10] to [1 5]. Otherwise the duplicate number is in the second half so for the next step the search space would be [6 10].
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
low = 1
high = len(nums)-1
while low < high:
mid = low+(high-low)/2
count = 0
for i in nums:
if i <= mid:
count+=1
if count <= mid:
low = mid+1
else:
high = mid
return low
view raw Q287-2.cpp hosted with ❤ by GitHub

LeetCode Q286: Walls and Gates


You are given a m x n 2D grid initialized with these three possible values.
  1. -1 - A wall or an obstacle.
  2. 0 - A gate.
  3. INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than2147483647.
Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF.
For example, given the 2D grid:
INF  -1  0  INF
INF INF INF  -1
INF  -1 INF  -1
  0  -1 INF INF
After running your function, the 2D grid should be:
  3  -1   0   1
  2   2   1  -1
  1  -1   2  -1
  0  -1   3   4
Solution:
BFS

class Solution {
public:
void Fill(vector<vector<int>>& rooms, int entry, int num, int width, int height){
int row = entry/width;
int col = entry%width;
rooms[row][col] = num;
if(row-1>=0 && rooms[row-1][col]>(num+1))
Fill(rooms, (row-1)*width+col, num+1, width, height);
if(col-1>=0 && rooms[row][col-1]>(num+1))
Fill(rooms, row*width+col-1, num+1, width, height);
if(row+1<=height-1 && rooms[row+1][col]>(num+1))
Fill(rooms, (row+1)*width+col, num+1, width, height);
if(col+1<=width-1 && rooms[row][col+1]>(num+1))
Fill(rooms, row*width+col+1, num+1, width, height);
}
void wallsAndGates(vector<vector<int>>& rooms) {
if(rooms.empty())
return;
int m = rooms.size();
int n = rooms[0].size();
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
if(rooms[i][j]==0)
Fill(rooms, i*n+j, 0, n, m);
}
};
view raw Q286.cpp hosted with ❤ by GitHub

LeetCode Q285: Inorder Successor in BST

Given a binary search tree and a node in it, find the in-order successor of that node in the BST.
Note: If the given node has no in-order successor in the tree, return null.

Solution:
Use stack to do in-order traversal.

/**
* 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:
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
stack<TreeNode*> myStack;
TreeNode* cur;
myStack.push(root);
cur = root->left;
bool metP=false;
while(cur!=NULL||!myStack.empty()){
if(cur==NULL){
TreeNode* node = myStack.top();
myStack.pop();
if(metP==true)
return node;
if(node == p)
metP=true;
cur = node->right;
continue;
}
myStack.push(cur);
cur=cur->left;
}
return NULL;
}
};
view raw Q285.cpp hosted with ❤ by GitHub


Round 2 solution:
/**
* 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:
TreeNode* InOrder(TreeNode* root, TreeNode* p, TreeNode*& lastAccessed){
if(root==NULL)
return NULL;
TreeNode* l = InOrder(root->left, p, lastAccessed);
if(lastAccessed==p){
lastAccessed=root;
return root;
}
lastAccessed=root;
TreeNode* r = InOrder(root->right, p, lastAccessed);
return l!=NULL? l:r!=NULL? r:NULL;
}
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
TreeNode* res=NULL;
if(root==NULL||p==NULL)
return NULL;
TreeNode* lastAccessed=NULL;
res = InOrder(root, p, lastAccessed);
return res;
}
};
view raw Q285Rnd2.cpp hosted with ❤ by GitHub

Monday, April 25, 2016

LeetCode Q284: Peeking Iterator

Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next().

Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3].
Call next() gets you 1, the first element in the list.
Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.
You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false.
Hint:
  1. Think of "looking ahead". You want to cache the next element.
  2. Is one variable sufficient? Why or why not?
  3. Test your design with call order of peek() before next() vs next() before peek().
  4. For a clean implementation, check out Google's guava library source code.
Solution 1.
Using copy constructor

// Below is the interface for Iterator, which is already defined for you.
// **DO NOT** modify the interface for Iterator.
class Iterator {
struct Data;
Data* data;
public:
Iterator(const vector<int>& nums);
Iterator(const Iterator& iter);
virtual ~Iterator();
// Returns the next element in the iteration.
int next();
// Returns true if the iteration has more elements.
bool hasNext() const;
};
class PeekingIterator : public Iterator {
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
// Initialize any member here.
// **DO NOT** save a copy of nums and manipulate it directly.
// You should only use the Iterator interface methods.
}
// Returns the next element in the iteration without advancing the iterator.
int peek() {
return Iterator(*this).next();
}
// hasNext() and next() should behave the same as in the Iterator interface.
// Override them if needed.
int next() {
return Iterator::next();
}
bool hasNext() const {
return Iterator::hasNext();
}
};
view raw Q284.cpp hosted with ❤ by GitHub

Solution 2:
Loof forward and cache the next element, need to use two variables. One for next element, one for hasNext.

// Below is the interface for Iterator, which is already defined for you.
// **DO NOT** modify the interface for Iterator.
class Iterator {
struct Data;
Data* data;
public:
Iterator(const vector<int>& nums);
Iterator(const Iterator& iter);
virtual ~Iterator();
// Returns the next element in the iteration.
int next();
// Returns true if the iteration has more elements.
bool hasNext() const;
};
class PeekingIterator : public Iterator {
private:
int m_next;
bool m_hasnext;
public:
PeekingIterator(const vector<int>& nums) : Iterator(nums) {
m_hasnext = Iterator::hasNext();
if (m_hasnext) m_next = Iterator::next();
}
int peek() {
return m_next;
}
int next() {
int t = m_next;
m_hasnext = Iterator::hasNext();
if (m_hasnext) m_next = Iterator::next();
return t;
}
bool hasNext() const {
return m_hasnext;
}
};
view raw Q284-2.cpp hosted with ❤ by GitHub

LeetCode Q283: Move Zeros

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
  1. You must do this in-place without making a copy of the array.
  2. Minimize the total number of operations.

Solution:

class Solution {
public:
void moveZeroes(vector<int>& nums) {
vector<int> zerosCount(nums.size(), 0);
int c=0;
for(int i=0; i<nums.size(); i++){
if(nums[i]==0){
c++; continue;
}else{
zerosCount[i]=c;
}
}
for(int i=0; i<nums.size(); i++){
if(zerosCount[i]==0)
continue;
nums[i-zerosCount[i]]=nums[i];
nums[i]=0;
}
}
};


Round 2 solution:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int zeros=0;
for(int i=0; i<nums.size(); i++){
if(nums[i]==0){
zeros++;
}else{
nums[i-zeros]=nums[i];
nums[i]=zeros>0? 0:nums[i];
}
}
}
};
view raw gistfile1.txt hosted with ❤ by GitHub

LeetCode Q282: Expression Add Operators (hard)

Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +-, or * between the digits so they evaluate to the target value.
Examples: 
"123", 6 -> ["1+2+3", "1*2*3"] 
"232", 8 -> ["2*3+2", "2+3*2"]
"105", 5 -> ["1*0+5","10-5"]
"00", 0 -> ["0+0", "0-0", "0*0"]
"3456237490", 9191 -> []

Solution:
In my first try, I try to save all intermediate results of all possible cut, which equivalent to a BFS soluton. However, it result in a overflow of memory. Because BFS has to record all cases.

The problem can be solved using DFS, which is much more efficient in terms of memory usage. To deal with priority of operator "*", we need to keep track the operator used in last round. Also, we need to rule out the case where nums get multiple leading "0"s.


class Solution {
public:
// cur: {string} expression generated so far.
// pos: {int} current visiting position of num.
// cv: {long} cumulative value so far.
// pv: {long} previous operand value.
// op: {char} previous operator used.
void dfs(std::vector<string>& res, const string& num, const int target, string cur, int pos, const long cv, const long pv, const char op) {
if (pos == num.size() && cv == target) {
res.push_back(cur);
} else {
for (int i=pos+1; i<=num.size(); i++) {
string t = num.substr(pos, i-pos);
long now = stol(t);
if (to_string(now).size() != t.size()) continue;
dfs(res, num, target, cur+'+'+t, i, cv+now, now, '+');
dfs(res, num, target, cur+'-'+t, i, cv-now, now, '-');
dfs(res, num, target, cur+'*'+t, i, (op == '-') ? cv+pv - pv*now : ((op == '+') ? cv-pv + pv*now : pv*now), pv*now, op);
}
}
}
public:
vector<string> addOperators(string num, int target) {
vector<string> res;
if (num.empty()) return res;
for (int i=1; i<=num.size(); i++) {
string s = num.substr(0, i);
long cur = stol(s);
if (to_string(cur).size() != s.size()) continue;
dfs(res, num, target, s, i, cur, cur, '#'); // no operator defined.
}
return res;
}
};
view raw Q282.cpp hosted with ❤ by GitHub

Saturday, April 23, 2016

LeetCode Q281: Zigzag Iterator

Given two 1d vectors, implement an iterator to return their elements alternately.
For example, given two 1d vectors:
v1 = [1, 2]
v2 = [3, 4, 5, 6]
By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1, 3, 2, 4, 5, 6].
Follow up: What if you are given k 1d vectors? How well can your code be extended to such cases?
Clarification for the follow up question - Update (2015-09-18):
The "Zigzag" order is not clearly defined and is ambiguous for k > 2 cases. If "Zigzag" does not look right to you, replace "Zigzag" with "Cyclic". For example, given the following input:


class ZigzagIterator {
public:
ZigzagIterator(vector<int>& _v1, vector<int>& _v2) {
v.push_back(_v1);
v.push_back(_v2);
size[0]=v[0].size();
size[1]=v[1].size();
p[0]=0;
p[1]=0;
nowat=0;
}
int next() {
int res=v[nowat][p[nowat]];
p[nowat]++;
nowat = nowat^1;
return res;
}
bool hasNext() {
if(p[nowat]>=size[nowat]){
nowat = nowat^1;
return p[nowat]<size[nowat];
}
return true;
}
vector<vector<int>> v;
int size[2];
int p[2];
int nowat;
};
view raw Q281.cpp hosted with ❤ by GitHub

LeetCode Q280: Wiggle Sort

Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3]....
For example, given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].

Solution:


class Solution {
public:
void wiggleSort(vector<int>& nums) {
int n = nums.size();
for (int i = 1; i < n; i++){
if(i%2==1 && nums[i]<nums[i-1])
swap(nums[i], nums[i-1]);
if(i%2==0 && nums[i]>nums[i-1])
swap(nums[i], nums[i-1]);
}
}
};
view raw Q280.cpp hosted with ❤ by GitHub

LeetCode Q279: Perfect Squares

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.
For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

Solutions:
One of trick to use is so called "Static DP", which use a static vector to save already computed results among huge number of test cases to same more time. But for single call, it is no difference to what I present here.

class Solution {
public:
int numSquares(int n) {
if(n<=0) return 0;
vector<int> M(n+1, INT_MAX);
M[0]=0;
for(int i=1; i<=n; i++)
for(int j=1; j*j<=i; j++)
M[i]=min(M[i], M[i-j*j]+1);
return M.back();
}
};
view raw Q279.cpp hosted with ❤ by GitHub

Round 3:
class Solution {
public:
int numSquares(int n) {
vector<int> myT(n+1, INT_MAX);
myT[0]=0;
for(int i=1; i<=n; i++){
for(int j=1; j*j<=i; j++)
myT[i] = min(myT[i], myT[i-j*j]+1);
}
return myT.back();
}
};
view raw Q279Rnd3.cpp hosted with ❤ by GitHub

LeetCode Q278: First Bad Version

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.
Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.
You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

Solution:

// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
long helper(long n, long left, long right){
if(left>right)
return -1;
int m = (left+right)/2;
bool b = isBadVersion(m);
if(!b)
return helper(n, m+1, right);
else{
if(m==1||!isBadVersion(m-1))
return m;
else
return helper(n, left, m-1);
}
}
int firstBadVersion(int n) {
long res=helper(n, 1, n);
return (int)res;
}
};
view raw Q278.cpp hosted with ❤ by GitHub


Round 2 solution:
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
long helper(long n, long l, long r){
int res;
if(l==r-1||l==r)
return isBadVersion(l+1)? l:r;
int m = (l+r)/2;
bool bad = isBadVersion(m+1);
if(bad)
res = helper(n, l, m);
else
res = helper(n, m, r);
return res;
}
int firstBadVersion(int n) {
long res=helper(n, 0, n-1);
return (int)res+1;
}
};
view raw Q278Rnd2.cpp hosted with ❤ by GitHub


Round 3 solution:
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int l = 1, r=n;
while(l<r-1){
int m = l+(r-l)/2;
bool tmp = isBadVersion(m);
if(tmp)
r=m;
else
l=m;
}
return isBadVersion(l)? l:r;
}
};
view raw Q278Rnd3.cpp hosted with ❤ by GitHub

LeetCode Q277: Find the Celebrity

Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense). You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows. Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a celebrity in the party. If there is no celebrity, return -1.

Solution:
The idea is as follows:
first, if person A knows person B, then B could be the candidate of being a celebrity, A must not be a celebrity. We iterate all the n persons and we will have a candidate that everyone knows this candidate.
second, we check two things after we get this candidate. 1. If this candidate knows other person in the group, if the candidate knows anyone in the group, then the candidate is not celebrity, return -1; 2. if everyone knows this candidate, if anyone does not know the candidate, return -1;

The second loop is necessary because, in the first loop, we could include the case where the candidate is happen to know someone shows before it.




// Forward declaration of the knows API.
bool knows(int a, int b);
class Solution {
public:
int findCelebrity(int n) {
if(n<=1) return n;
int candidate = 0;
for(int i=1; i<n; i++)
if ( !knows(i,candidate) )
candidate = i;
for(int j=0; j<n; j++){
if(j== candidate) continue;
if( !knows(j,candidate) || knows(candidate,j) ) return -1;
}
return candidate;
}
};
view raw Q277.cpp hosted with ❤ by GitHub

LeetCode Q276: Paint Fence.

There is a fence with n posts, each post can be painted with one of the k colors.
You have to paint all the posts such that no more than two adjacent fence posts have the same color.
Return the total number of ways you can paint the fence.
Note:
n and k are non-negative integers.

Solution:
Using DP. To know how many ways to paint current house, we need to know two things. First, the total number of ways to paint previous houses. Second, We need to know whether the house in the last round is paint the color as same as the house before it.
So, we can create a Nx2 array to same the total number of ways to paint current n houses for first the current house is paint differently with previous one and second the current house is paint the same color as previous one.
To further optimize the code, could just use two variable to save results.


class Solution {
public:
int numWays(int n, int k) {
if(n<=1||k<=0)
return n==0? 0:k;
vector<vector<int> > N(n+1, vector<int> (2, 0));
N[0][0]=k; N[0][1]=1;
N[1][0]=N[0][0]*(k-1); N[1][1]=N[0][0];
for(int i=2; i<n; i++){
int v00 = N[i-1][0]*(k-1); // not same, not same
int v01 = N[i-1][0]; // not same, same
int v10 = N[i-1][1]*(k-1); // same, not same
N[i][0] = v00+v10;
N[i][1] = v01;
}
return N[n-1][0] + N[n-1][1];
}
};
view raw Q276.cpp hosted with ❤ by GitHub

Round 2 solution:
For the first post, there is total k ways to paint it. For the second post, if it is paint differently than first one, there is (k-1)*k ways, it is paint in a same way, there is k. Starting from the 3rd post, if paint differently, we add up the case where first if previous one was paint differently, second if previous one is paint same.


class Solution {
public:
int numWays(int n, int k) {
if(n==0||k<=0)
return 0;
int pre[2] = {k, 0};
for(int i=1; i<n; i++){
int notSame = pre[0]*(k-1)+pre[1]*(k-1);
int same = pre[0];
pre[0]=notSame;
pre[1]=same;
}
return pre[0]+pre[1];
}
};
view raw Q276Rnd2.cpp hosted with ❤ by GitHub