LineIntersections
http://www.cs.toronto.edu/~robere/csc373h/files/A2-sol.pdf
search "3. Line Intersections (Redux)"
search "3. Line Intersections (Redux)"
A-Z
is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26Given an encoded message containing digits, determine the total number of ways to decode it.
"12"
, it could be decoded as "AB"
(1 2) or "L"
(12). "12"
is 2.
1. Dynamic Programming
class Solution {
public:
int numDecodings(string s) {
int n = s.length();
if (n < 1) return 0;
if (s[0] == '0') return 0;
vector<int> ways(n+1, 0);
ways[0] = 1, ways[1] = 1;
for(int i = 2; i <= n; i++) {
ways[i] = ways[i-1];
if (s[i-1] == '0') {
if (s[i-2] == '0' || s[i-2] > '2')
return 0;
else
ways[i] = ways[i-2];
}
else {
if ((s[i-2] == '1') || (s[i-2] == '2' && s[i-1] < '7')) ways[i] += ways[i-2];
}
}
return ways[n];
}
};
2. Notice we look up from no more than two previous result. We can use something similar to calculating Fibonacci series:
class Solution {
public:
int numDecodings(string s) {
int n = s.length();
if (n < 1) return 0;
int T_2 = 1, T_1 = 1;
for(int i =0 ; i < n; i++) {
int T = T_1;
if (s[i] == '0') {
if (i == 0 ||(s[i-1] == '0' || s[i-1] > '2'))
return 0;
else
T = T_2;
}
else if (i > 0 && (s[i-1] == '1' || (s[i-1] == '2' && s[i] < '7')))
T+= T_2;
T_2 = T_1;
T_1 = T;
}
return T_1;
}
};
'.'
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
Solution 1, Recursion:
bool isMatch(const char *s, const char *p) {
if (!*p) return !*s;
if (*(p+1) != '*') { return (*p == *s ||(*s && *p == '.')) && isMatch(s+1, p+1);}
while(*s == *p || (*p == '.' && *s)) {
if (isMatch(s, p+2)) return true;
s++;
}
return isMatch(s, p+2);
}
Solution 2. DP
class Solution {
public:
bool isMatch(const char *s, const char *p) {
if (!*p) return !*s;
int m = strlen(p);
int n = strlen(s);
vector<vector<bool>> match(m+1, vector<bool>(n+1, false));
match[0][0] = 1;
match[1][1] = s[0] == p[0] || p[0] == '.';
// When s is empty, but p = '.*', p matches s
for(int i = 2; i <=m; i++)
match[i][0] = p[i-1] == '*'? match[i-2][0] : false;
// starting from second char in p
for(int i = 2; i <= m; i++)
for(int j = 1; j <= n; j++)
if (p[i-1]== '*')
match[i][j] = isSame(s[j-1], p[i-2])? match[i-2][j] || match[i-2][j-1] || match[i-1][j-1] || match[i][j-1] : match[i-2][j];
else
match[i][j] = isSame(s[j-1], p[i-1]) && match[i-1][j-1];
return match[m][n];
}
bool isSame(char a, char b){
return (a == b || b=='.');
}
};
//
// D[i][j] = | D[i-1][j-1]) A[i] == A[j]
// |
// | 1 + min(D[i][j-1], D[i-1][j], D[i-1][j-1]) A[i] != A[j]
//
class Solution {
public:
int minDistance(string A, string B) {
int m = A.size();
int n = B.size();
vector<int> D(n + 1, 0);
for(int j = 0; j <=n; j++)
D[j] = j;
for(int i = 1; i <= m; i++) {
int D_i_1_j_1 = i-1; // D[i-1][0]
D[0] = i; // D[i][0]
for(int j = 1; j <= n; j++) {
int T = A[i-1] == B[j-1] ? D_i_1_j_1 : 1 + min(D[j-1], min(D[j], D_i_1_j_1));
D_i_1_j_1 = D[j];
D[j] = T;
}
}
return D[n];
}
};
// DP2
class Solution {
public:
int minDistance(string word1, string word2) {
int m = word1.length();
int n = word2.length();
if(m == 0) return n;
if(n==0) return m;
vector<vector<int>> map(m+1);
for(int i = 0;i < m+1; i++)
map[i] = vector<int>(n+1, 0);
for(int i = 0; i <=m; i++)
map[i][0] =i;
for(int i = 0; i <=n; i++)
map[0][i] =i;
for (int i = 1; i <=m; i++)
for (int j = 1; j <=n; j++)
{
if (word1[i-1] == word2[j-1])
map[i][j] = map[i-1][j-1];
else {
map[i][j] = min(map[i-1][j], map[i][j-1]);
map[i][j] = min(map[i][j], map[i-1][j-1]);
map[i][j] +=1;
}
}
return map[m][n];
}
};
// DP 3
class Solution {
public:
int minDistance(string word1, string word2) {
int l1 = word1.size();
int l2 = word2.size();
vector<int> f(l2+1, 0);
for (int j = 1; j <= l2; ++j)
f[j] = j;
for (int i = 1; i <= l1; ++i)
{
int prev = i;
for (int j = 1; j <= l2; ++j)
{
int cur;
if (word1[i-1] == word2[j-1]) {
cur = f[j-1];
} else {
cur = min(min(f[j-1], prev), f[j]) + 1;
}
f[j-1] = prev;
prev = cur;
}
f[l2] = prev;
}
return f[l2];
}
};
"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
// Sol1 http://www.mitbbs.com/article_t1/JobHunting/32787241_0_2.html
class Solution {
public:
bool isNumber(const char *s) {
if (!s) return false;
while(*s == ' ')
s++;
// sign
if (*s == '+' || *s == '-')
s++;
int n = getDigits(s);
if (*s == '.') {
s++;
n += getDigits(s);
}
// digits before and after '.' must > 0, ".1" is valid
if (n < 1) return false;
if (*s == 'e') {
s++;
if (*s == '+' || *s == '-')
s++;
n = getDigits(s);
if (n < 1) return false;
}
// trailing spaces is fine.
while(*s == ' ') s++;
return *s == NULL;
}
// count valid digits and move pointer
int getDigits(const char *&s){
int count = 0;
while (*s >='0' && *s <='9'){
count++;
s++;
}
return count;
}
};
// http://n00tc0d3r.blogspot.com/2013/06/valid-number.html
class Solution {
public:
bool isNumber(const char *s) {
int fsm[][9] = {
{0, 8, -1, -1, 8, -1, -1, 8, 8},
{2, -1, -1, -1, -1, 6, -1, -1, -1},
{1, 1, 1, 4, 4, 7, 7, 7, -1},
{3, 4, 3, -1, -1, -1, -1, -1, -1},
{-1, 5, -1, -1, 5, -1, -1, -1, -1}
};
int state = 0;
while(*s)
{
int in = getInput(s);
if (in < 0) return false;
state = fsm[in][state];
if (state < 0) return false;
s++;
}
return state == 1 || state == 4 || state == 7 || state == 8;
}
// Space(0), Sign(1), Digit(2), Dot(3), Exp(4), Else(-1);
int getInput(const char *s) {
int out = -1;
switch (*s) {
case ' ': return 0;
case '+':
case '-': return 1;
case '.': return 3;
case 'e': return 4;
}
if (*s >='0' && *s <='9') return 2;
return -1;
}
};
'?'
and '*'
.'?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). 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", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", "c*a*b") → false
// Solution 1
class Solution {
public:
bool isMatch( const char *s, const char *p) {
while(*s && *p != '*') {
if (*s != *p && *p != '?') return false;
s++;
p++;
}
const char *ps = NULL;
const char *pp = NULL;
while(*s) {
if (*p == '*') {
if (!*++p) return true;
ps = s;
pp = p;
}
else if (*s == *p || *p== '?') {
s++; p++;
}
else {
s = ++ps;
p = pp;
}
}
while(*p == '*') p++;
return !*p;
}
};
// Solution 2 similar to 1 but a little more concise
bool isMatch( const char *s, const char *p) {
const char *ps = NULL;
const char *pp = NULL;
while(*s) {
if (*p == '*') {
if (!*++p) return true;
ps = s + 1;
pp = p;
}
else if (*s == *p || *p == '?') {
s++;
p++;
}
else if (ps)
{
s = ps++;
p = pp;
}
else return false;
}
while(*p == '*') p++;
return !*p;
}
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
/*
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> output;
if (!root) return output;
TreeNode *prev = NULL;
stack<TreeNode *> st;
st.push(root);
while(!st.empty())
{
TreeNode *cur = st.top();
if (prev == NULL || prev->left == cur || prev->right == cur)
{
if (cur->left) {
st.push(cur->left);
} else if (cur->right) {
st.push(cur->right);
} else {
output.push_back(cur->val);
st.pop();
}
}
else if (cur->right == prev) {
st.pop();
output.push_back(cur->val);
}
else if (cur->left == prev) {
if (cur->right) {
st.push(cur->right);
}
else {
st.pop();
output.push_back(cur->val);
}
}
prev = cur;
}
return output;
}
};
*/
/*Method 1
vector<int> postorderTraversal(TreeNode *root) {
vector<int> output;
if (!root) return output;
TreeNode *prev = NULL;
stack<TreeNode *> st;
st.push(root);
while(!st.empty())
{
TreeNode *cur = st.top();
if (!cur->left && !cur->right) {
output.push_back(cur->val);
st.pop();
}
if (cur->right) {
st.push(cur->right);
cur->right= NULL;
}
if (cur->left) {
st.push(cur->left);
cur->left = NULL;
}
}
return output;
}
// Method 2
vector<int> postorderTraversal(TreeNode *root) {
vector<int> output;
if (!root) return output;
TreeNode *prev = NULL;
stack<TreeNode *> st;
stack<TreeNode *> st2;
st.push(root);
while(!st.empty())
{
TreeNode *cur = st.top();
st.pop();
st2.push(cur);
if (cur->left)
st.push(cur->left);
if (cur->right)
st.push(cur->right);
}
while(!st2.empty()){
TreeNode *cur = st2.top();
st2.pop();
output.push_back(cur->val);
}
return output;
}
// Method 3
vector<int> postorderTraversal(TreeNode *root) {
vector<int> output;
stack<TreeNode *> st;
while(!st.empty() || root)
{
if (!root)
{
while(!st.empty() && root==st.top()->right)
{
root= st.top();
st.pop();
output.push_back(root->val);
}
root= st.empty()? NULL : st.top()->right;
}
else
{
st.push(root);
root = root->left;
}
}
return output;
}
*/
// Simple coder's solution
vector<int> postorderTraversal(TreeNode *root) {
vector<int> output;
stack<TreeNode*> st;
TreeNode *prev = NULL;
pushLeft(root, st);
while (!st.empty()) {
root = st.top();
if (prev == root->left && root->right)
{
pushLeft(root->right, st);
prev = NULL;
}
else
{
output.push_back(root->val);
st.pop();
prev = root;
}
}
return output;
}
void pushLeft(TreeNode *root, stack<TreeNode *> &st)
{
while(root) {
st.push(root);
root = root->left;
}
}
};
label
and a list of its neighbors
. #
as a separator for each node, and ,
as a separator for node label and each neighbor of the node. {0,1,2#1,2#2,2}
. #
. 0
. Connect node 0
to both nodes 1
and 2
.1
. Connect node 1
to node 2
.2
. Connect node 2
to node 2
(itself), thus forming a self-cycle.1 / \ / \ 0 --- 2 / \ \_/
/**
* Definition for undirected graph.
* struct UndirectedGraphNode {
* int label;
* vector<UndirectedGraphNode *> neighbors;
* UndirectedGraphNode(int x) : label(x) {};
* };
*/
class Solution {
public:
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if (!node) return NULL;
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> map;
queue<UndirectedGraphNode *> que;
que.push(node);
map[node] = new UndirectedGraphNode(node->label);
while(!que.empty()) {
UndirectedGraphNode *current = que.front();
que.pop();
for(auto iter : current->neighbors) {
if (map.find(iter) == map.end()) {
map[iter] = new UndirectedGraphNode(iter->label);
que.push(iter);
}
map[current]->neighbors.push_back(map[iter]);
}
}
return map[node];
}
};
class Solution {
public:
void BFS(UndirectedGraphNode *node, unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> &map)
{
if (map[node]) return;
map[node] = new UndirectedGraphNode(node->label);
for(UndirectedGraphNode *child : node->neighbors)
BFS(child, map);
}
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if (!node) return NULL;
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> map;
BFS(node, map);
for(auto iter:map)
for(UndirectedGraphNode *child : iter.first->neighbors)
iter.second->neighbors.push_back(map[child]);
return map[node];
}
};
class Solution {
public:
UndirectedGraphNode *DFS(UndirectedGraphNode *node, unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> &map)
{
if (map[node]) return map[node];
UndirectedGraphNode *nn = new UndirectedGraphNode(node->label);
map[node] = nn;
for(UndirectedGraphNode *child : node->neighbors)
nn->neighbors.push_back(DFS(child, map));
return nn;
}
UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
if (!node) return NULL;
unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> map;
return DFS(node, map);
}
};
class Solution {
public:
int atoi(const char *str) {
while(*str && *str == ' ') str++;
int sign = 1;
if (*str == '+' || *str=='-') {
sign = *str == '+'? 1 : -1;
str++;
}
long val = 0;
while(*str >= '0' && *str <='9') {
if (sign == 1 && ((*str >= '8' && val == INT_MAX/10) || val > INT_MAX/10) ) return INT_MAX;
if (sign == -1 && ((*str >= '8' && val == INT_MAX/10) || val > INT_MAX/10) ) return INT_MIN;
val = val *10 + *str -'0';
str++;
}
val *=sign;
return val;
}
};
"PAYPALISHIRING"
is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I RAnd then read line by line:
"PAHNAPLSIIGYIR"
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3)
should return "PAHNAPLSIIGYIR"
.
class Solution {
public:
string convert(string s, int nRows) {
if (nRows < 2) return s;
int n = s.length();
int groupLen = 2*nRows-2;
int groups = 1 + n / groupLen;
string output;
for(int i = 0; i < nRows; i++)
{
for(int j = 0; j < groups; j++ )
{
if (i == 0 || i == nRows-1)
{
if (j * groupLen + i <n)
output.push_back(s[j * groupLen + i]);
}
else {
if (j * groupLen + i <n)
output.push_back(s[j * groupLen + i]);
if ((j+1) * groupLen - i <n)
output.push_back(s[(j+1) * groupLen - i]);
}
}
}
return output;
}
};
class Solution {
public:
string convert(string s, int nRows) {
if (nRows < 2) return s;
vector<string> map(nRows, "");
int groupLen = 2*nRows-2;
for(int i = 0; i < s.length(); i++)
{
int index = i % groupLen;
if (index <nRows)
map[index].push_back(s[i]);
else
map[groupLen-index].push_back(s[i]);
}
string output = "";
for(string str:map)
output += str;
return output;
}
};
// http://www.mitbbs.com/article_t/JobHunting/32823417.html
// http://www.matrix67.com/blog/archives/115
class Solution {
public:
vector<int> KMPpreprocessing(char *needle) {
int m = strlen(needle);
// assume j = match[i]: needle[i-j:i] == needle[0:j]
vector<int> match(m,-1);
int j = -1;
for(int i=1; i<m; i++) {
while(j>=0 && needle[i]!=needle[j+1]) j = match[j];
if(needle[i]==needle[j+1]) j++;
match[i] = j;
}
return match;
}
int strStr(char *haystack, char *needle) {
if(!*needle) return 0;
if(!*haystack) return -1;
int n = strlen(haystack);
int m = strlen(needle);
vector<int> match = KMPpreprocessing(needle);
int j = -1;
for(int i=0; i<n; i++) {
while(j>=0 && haystack[i]!=needle[j+1]) j = match[j];
if(haystack[i]==needle[j+1]) j++;
if(j==m-1) return i-m+1;
}
return -1;
}
};
[2,3,1,1,4]
, return true
. [3,2,1,0,4]
, return false
.
class Solution {
public:
bool canJump(int A[], int n) {
int current = 0;
int reach = A[0];
while(current <= reach) {
if (reach >= n-1) return true;
reach = max(reach, current+A[current]);
current++;
}
return false;
}
};
[2,3,1,1,4]
2
. (Jump 1
step from index 0 to 1, then 3
steps to the last index.)
class Solution {
public:
int jump(int A[], int n) {
if (n <= 1) return 0;
int current = 0;
int reach = A[0];
int jumps = 1;
while(reach < n-1)
{
int maxReach = 0;
for(int i = current+1; i <=reach; i++)
maxReach = max(maxReach, i+A[i]);
current = reach;
reach = maxReach;
jumps++;
}
return jumps;
}
};
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size();
if (n <= 1) return 0;
int current = 1;
int reach = nums[0];
int jumps = 1;
while(reach < n-1)
{
int maxReach = 0;
while(current <=reach) {
maxReach = max(maxReach, current+nums[current]);
current++;
}
reach = maxReach;
jumps++;
}
return jumps;
}
};
class Solution {
public:
bool canPlace(const vector<int> &placed, int row, int col)
{
for (int i = 0; i < row; i++)
{
if (placed[i] == col || abs(placed[i]-col) == row-i)
return false;
}
return true;
}
int totalNQueens(int n) {
int output = 0;
vector<int> placed(n, 0);
int row = 0, col = 0;
while(true) {
if (col == n) {
if(row == 0) return output;
else {
row--;
col = placed[row]+1;
continue;
}
}
if (canPlace(placed, row, col)) {
placed[row] = col;
if (row == n-1) {
output++;
col++;
}
else {
row++;
col = 0;
}
}
else
col++;
}
}
};
'Q'
and '.'
both indicate a queen and an empty space respectively.[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]
class Solution {
public:
bool isValid(vector<int> placement, int row)
{
for(int i = 0; i< row; i++)
if (placement[i] == placement[row] || row - i == abs(placement[i] - placement[row]))
return false;
return true;
}
vector<string> getBoard(const vector<int> &placed)
{
vector<string> output;
for(int i = 0; i < placed.size(); i++)
{
string temp;
for(int j = 0; j < placed.size(); j++)
temp.push_back(j==placed[i]?'Q':'.');
output.push_back(temp);
}
return output;
}
void helper(int n, int row, vector<int>& placement, vector<vector<string>> &ans){
if (row == n) {
ans.push_back(getBoard(placement));
return;
}
for(int i = 0;i < n; i++) {
placement[row] = i;
if (isValid(placement, row))
helper(n, row+1, placement, ans);
}
}
vector<vector<string> > solveNQueens(int n) {
vector<vector<string>> ans;
vector<int> placement(n);
helper(n, 0, placement, ans);
return ans;
}
};
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> output;
vector<int> placed(n, 0);
int row = 0, col = 0;
while(true) {
if (col == n) {
if(row == 0) return output;
else {
row--;
col = placed[row]+1;
continue;
}
}
if (canPlace(placed, row, col)) {
placed[row] = col;
if (row == n-1) {
output.push_back(getBoard(placed));
col++;
}
else {
row++;
col = 0;
}
}
else
col++;
}
return output;
}
1 2 3 4
8 7 6 5
The columns show which teams will play in that round (1 vs 8, 2 vs 7, ...).1 8 2 3
7 6 5 4
and in week 3, you get1 7 8 2
6 5 4 3
This continues through week n-1, in this case,1 3 4 5
2 8 7 6
If n is odd, do the same thing but add a dummy team. Whoever is matched against the dummy team gets a bye that week.
// C++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
typedef pair<int, int> PairInt;
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<PairInt, vector<PairInt>, greater<PairInt> > q;
// initialize heap with first element from each list
int k = lists.size();
for (int i = 0; i < k; i++) {
if (lists[i]) {
q.push(PairInt(lists[i]->val, i));
}
}
ListNode tmp(0);
ListNode *p = &tmp;
while (!q.empty()) {
int i = q.top().second;
q.pop();
p->next = lists[i];
p =p->next;
lists[i] = lists[i]->next;
if (lists[i]) {
q.push(PairInt(lists[i]->val, i));
}
}
return tmp.next;
}
};
// Java
public ListNode mergeKLists(ArrayList<ListNode> lists) {
if (lists == null || lists.size() == 0) { // this was missed.
return null;
}
// PriorityQueue is the heap implementation in Java
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>(lists.size(), new Comparator<ListNode>() {
public int compare(ListNode l1, ListNode l2) {
return l1.val - l2.val;
}
});
for (ListNode head : lists) {
if (head != null) { // this was missed.
pq.add(head);
}
}
ListNode head = new ListNode(0);
ListNode p = head;
while (pq.size() > 0) {
p.next = pq.poll();
p = p.next; // this was missed.
if (p.next != null) {
pq.add(p.next);
}
}
return head.next;
}
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1
\
2
/
3
return [1,3,2]
.
Note: Recursive solution is trivial, could you do it iteratively?
class Solution { /** * @param root: The root of binary tree. * @return: Inorder in vector which contains node values. */ public: vector<int> inorderTraversal(TreeNode *root) { vector<int> output; stack<TreeNode *> st; while (root || !st.empty()){ if (!root) { root = st.top(); st.pop(); output.push_back(root->val); root = root->right; } else { st.push(root); root = root->left; } } return output; } };
//Morris Traversal vector<int> inorderTraversal(TreeNode *root) { vector<int> output; while(root) { if (root->left) { TreeNode *prev = root->left; while(prev->right != NULL && prev->right != root) prev = prev->right; if (!prev->right) { prev->right = root; root =root->left; } else { prev->right = NULL; output.push_back(root->val); root = root->right; } } else { output.push_back(root->val); root = root->right; } } return output; } class Solution { void pushLeft(TreeNode *root, stack<TreeNode *> &st) { while(root) { st.push(root); root = root->left; } }
class Solution { void pushLeft(TreeNode *root, stack<TreeNode *> &st) { while(root) { st.push(root); root = root->left; } } public: vector<int> inorderTraversal(TreeNode *root) { vector<int> output; stack<TreeNode*> st; pushLeft(root, st); while (!st.empty()) { root = st.top(); st.pop(); output.push_back(root->val); pushLeft(root->right, st); } return output; } };
class DllNode
{
public:
DllNode *prev;
DllNode *next;
int val;
int key;
DllNode(int key, int val)
{
this->key = key;
this->val = val;
this->prev = this;
this->next = this;
}
void Detach()
{
prev->next = next;
next->prev = prev;
}
void AddLeft(DllNode *node)
{
prev->next = node;
node->prev = prev;
node->next = this;
prev = node;
}
};
class LRUCache{
public:
int m_cap;
DllNode m_head;
unordered_map<int, DllNode *> m_map;
LRUCache(int capacity): m_head(0,0)
{
m_cap = capacity;
}
int get(int key) {
if (m_map.count(key) ==0)
return -1;
DllNode *node = m_map[key];
node->Detach();
m_head.AddLeft(node);
return node->val;
}
void set(int key, int value) {
if (m_map.find(key) != m_map.end())
{
DllNode *node = m_map[key];
node->Detach();
delete node;
m_map.erase(key);
}
if (m_map.size() == m_cap)
{
DllNode *oldest = m_head.next;
oldest->Detach();
m_map.erase(oldest->key);
delete oldest;
}
DllNode *node = new DllNode(key, value);
m_head.AddLeft(node);
m_map[key] = node;
}
};
ListNode *insertionSortList(ListNode *head) {
if (!head) return head;
ListNode dummy(numeric_limits<int>::min());
while(head) {
ListNode *p = &dummy;
while(p->next && p->next->val <= head->val)
p = p->next;
ListNode *headNext = head->next;
head->next = p->next;
p->next = head;
head = headNext;
}
return dummy.next;
}
ListNode *sortList(ListNode *head) {
// Notice the second condition check, other wise, stack overflow.
if (!head || !head->next) return head;
ListNode *fast = head, *slow = head;
while(fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
fast = slow->next;
slow->next = NULL;
return merge(sortList(head), sortList(fast));
}
ListNode *merge(ListNode *left, ListNode *right)
{
ListNode dummy(0);
ListNode *p = &dummy;
while(left && right)
{
if (left->val < right->val) {
p->next = left;
left = left->next;
}
else {
p->next = right;
right = right->next;
}
p = p->next;
}
p->next = left? left : right;
return dummy.next;
}
Solution 1:
int maxPoints(vector<Point> &points){
int n = points.size();
if (n < 3) return n;
int ret = 0;
for (int i = 0; i < n; i++) {
unordered_map<double, int> slopes;
int dup = 1;
int localMax = 0;
for(int j = i+1; j < n; j++) {
if (points[i].x == points[j].x && points[i].y == points[j].y)
dup++;
else {
double x = points[i].x - points[j].x;
double y = points[i].y - points[j].y;
double slop = x == 0? numeric_limits<double>::max() : y/x;
localMax = max(localMax, ++slopes[slop]);
}
}
ret = max(ret, dup+localMax);
}
return ret;
}
Solution 2:
int maxPoints(vector<Point> &points){
int n = points.size();
if (n < 3) return n;
int ret = 0;
for (int i = 0; i < n; i++)
{
unordered_map<int, unordered_map<int, int>> slopes;
int dup = 1;
int localMax = 0;
for(int j = i+1; j < n; j++)
{
if (points[i].x == points[j].x && points[i].y == points[j].y)
dup++;
else
{
int x = points[i].x - points[j].x;
int y = points[i].y - points[j].y;
int gcd = GCD(x, y);
if (gcd != 0)
{
x /= gcd;
y /= gcd;
}
localMax = max(localMax, ++slopes[x][y]);
}
}
ret = max(ret, dup+localMax);
}
return ret;
}
int GCD(int a, int b)
{
if (b == 0) return a;
return GCD(b, a%b);
}
Solution 3:
bool equals(float a, float b)
{
return abs(a-b) <= 1.0e-9;
}
int LongestPoints(vector<float> &slopes)
{
sort(slopes.begin(), slopes.end());
int n = slopes.size();
int counter = 1;
int start = 0;
int output = 0;
for(int i =1; i < n; i++)
{
if (!equals(slopes[i], slopes[i-1]))
{
output = max(output, i-start);
start = i;
}
}
output = max(output, n-start);
return output;
}
int maxPoints(vector<Point> &points)
{
int n = points.size();
if (n < 3) return n;
int maxPts = 2;
for (int i = 0; i < n; i++)
{
vector<float> slopes;
int dup = 1;
for(int j = i+1; j < n; j++)
{
float slope = numeric_limits<float>::max();
if (points[i].x == points[j].x && points[i].y == points[j].y)
dup++;
else {
if (points[i].x != points[j].x)
slope = (float)(points[i].y-points[j].y)/(float)(points[i].x-points[j].x);
slopes.push_back(slope);
}
}
int longestPoints = LongestPoints(slopes);
maxPts = max(maxPts, dup + longestPoints);
}
return maxPts;
}
Solution 1 (in Java):
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<Integer>();
for(String token : tokens)
{
if ("+".equals(token))
stack.push(stack.pop() + stack.pop());
else if("-".equals(token))
stack.push(-stack.pop() + stack.pop());
else if("*".equals(token))
stack.push(stack.pop() * stack.pop());
else if("/".equals(token))
{
int d1 = stack.pop();
int d2 = stack.pop();
stack.push(d2/d1);
}
else stack.push(Integer.parseInt(token));
}
return stack.pop();
}
Solution 2 (in C++):
bool isOperator(string &o)
{
return o == "+" || o == "-" || o == "*" || o == "/";
}
int atoi(const string &a)
{
int o = 0;
int i = 0;
int sign = 1;
while(i < a.length())
{
if (i == 0 && a[i] == '-') {
sign = -1;
i++;
continue;
}
o= o*10 + a[i]-'0';
i++;
}
return o*sign;
}
int eval(int left, const string &op, int right)
{
int r = 0;
if(op == "+")
return left+ right;
if(op == "-")
return left - right;
if(op == "*")
return left * right;
if(op == "/")
return left / right;
return 0;
}
int evalRPN(vector<string> &tokens) {
stack<int> mystack;
for(int i = 0; i < tokens.size(); i++)
{
if (isOperator(tokens[i]))
{
int right = mystack.top();
mystack.pop();
int left = mystack.top();
mystack.pop();
mystack.push(eval(left, tokens[i], right));
}
else
mystack.push(atoi(tokens[i]));
}
return mystack.top();
}
Solution 1:
void reverseWords(string &s) {
string output = "";
int len = 0;
for(int i = s.length()-1; i >=0; i--)
{
if (s[i] != ' ')
len++;
if (len > 0 && (i==0 || s[i-1] == ' '))
{
if (output.length() >0) output += " ";
output += s.substr(i, len);
len = 0;
}
}
s = output;
}
Solution 2:
void reverseWords(string &s) {
stack<string> st;
string word = "";
for(char c: s)
{
if (c == ' ')
{
if (word != "")
{
st.push(word);
word = "";
}
}
else
word += c;
}
if (word != "") st.push(word);
s ="";
if (st.size() >= 1)
{
s = st.top();
st.pop();
}
while(st.size() > 0)
{
s += " " + st.top();
st.pop();
}
}
Solution 1:
int maxProduct(int A[], int n) {
int max=A[0], min = A[0], ans = A[0];
for(int i = 1; i < n; i++) {
int mx = max, mn = min;
max = std::max(A[i], std::max(mx*A[i], mn*A[i]));
min = std::min(A[i], std::min(mx*A[i], mn*A[i]));
ans = std::max(ans, max);
}
return ans;
}
Solution 2:
int maxProduct(int A[], int n) {
int max = A[0];
int maxPos = 1.0;
int minNeg = 1.0;
for(int i = 0; i < n; i++) {
if (A[i] > 0) {
maxPos *= A[i];
minNeg = min(1, minNeg*A[i]);
max = std::max(max,maxPos);
}
else if (A[i] < 0) {
int tmp = maxPos * A[i];
if (minNeg < 0) {
maxPos = std::max(1, minNeg * A[i]);
max = std::max(max,maxPos);
}
else
maxPos = 1;
minNeg = tmp;
}
else {
maxPos = 1.0;
minNeg = 1.0;
max = std::max(0, max);
}
}
return max;
}
int findMin(vector<int> &num) {
int l = 0, r = num.size()-1;
while(l < r) {
int m = l + (r-l) /2;
if (num[m] < num[r])
r = m;
else
l = m +1;
}
return num[r];
}
int findMin(vector<int> &A) {
int l = 0, r = A.size()-1;
while(l < r) {
if (A[l] < A[r])
break;
int m = l + (r-l)/2;
if (A[m] < A[r])
r = m;
else if (A[m] > A[r])
l = m+1;
else {
r--;
l++;
}
}
return A[l];
}