Commit 89635d80 authored by anqiwa's avatar anqiwa 😲
Browse files

11/12/21 update

parent 4d2c7601
/*
* @lc app=leetcode id=1010 lang=cpp
*
* [1010] Pairs of Songs With Total Durations Divisible by 60
*/
// @lc code=start
class Solution
{
public:
int numPairsDivisibleBy60(vector<int> &time)
{
// inspired by two sum
// space: O(n*max)
// time: (n*max)
unordered_map<int, int> map; // {diff, frq}
int res = 0;
int max = 1000 / 60;
for (int i = 0; i < time.size(); ++i)
{
if (map.find(time[i]) != map.end())
res += map[time[i]];
for (int j = 1; j <= max; ++j)
{
map[j * 60 - time[i]]++;
}
}
return res;
}
};
// @lc code=end
// time[i] duration of i the song in sec
// return i,j s.t. (time[i] + time[j]) % 60 == 0
//[60, 60, 60] output = 3
// 60 120 ... 1000 / 60 =
// map <diff, frq>
// 480 / 60 == 8
//[60, 1]
\ No newline at end of file
/*
* @lc app=leetcode id=1041 lang=cpp
*
* [1041] Robot Bounded In Circle
*/
// @lc code=start
class Solution
{
public:
bool isRobotBounded(string instructions)
{
// N:(0,1), S(0,-1), w(-1,0), E(1,0)
pair<int, int> dir = {0, 1}; //{x,y}
pair<int, int> pos = {0, 0}; // pos from origin
for (auto ch : instructions)
{
if (ch == 'G')
{
pos.first += dir.first;
pos.second += dir.second;
}
else if (ch == 'L')
{
auto prev = dir;
dir.first = -prev.second;
dir.second = prev.first;
}
else
{
auto prev = dir;
dir.first = prev.second;
dir.second = -prev.first;
}
} //for
// two cases that will form a cycle
// case 1: if the robot return back to origin
// case 2: if the robot has dir that is not point to north
if (pos.first == 0 && pos.second == 0)
return true;
else if (dir.first != 0 || dir.second != 1)
return true;
return false;
}
};
// @lc code=end
// (0,1) -> (-1, 0)
// (0,1) -> (1, 0)
//O(n), n is the size of string
\ No newline at end of file
class Solution
{
public:
vector<string> mostVisitedPattern(vector<string> &user, vector<int> &t, vector<string> &site)
{
//1. Use a hash map of maps to group users and sort their visits (map).
//2. For each user, collect all 3-sequences using a hash set (ts).
//3. Count 3-sequences between users using a hash map (count);
//4. Find and return the 3-sequence with the largest count.
unordered_map<string, map<int, string>> map; //{user, map{timestamp, site}}
// site now sorted by map in nlogn
unordered_map<string, int> count;
//nlogn
for (auto i = 0; i < user.size(); ++i)
map[user[i]][t[i]] = site[i];
for (auto &u : map)
{
unordered_set<string> ts;
for (auto it = begin(u.second); it != end(u.second); ++it)
for (auto it1 = next(it); it1 != end(u.second); ++it1)
for (auto it2 = next(it1); it2 != end(u.second); ++it2)
ts.insert(it->second + " " + it1->second + " " + it2->second);
for (auto s : ts)
++count[s];
}
pair<string, int> resPair = *count.begin();
for (auto &pair : count)
{
if (pair.second > resPair.second)
{
resPair = pair;
}
else if (pair.second == resPair.second)
{
if (resPair.first > pair.first)
resPair = pair;
}
}
stringstream ss(resPair.first);
vector<string> resVec;
string word;
while (ss >> word)
{
resVec.push_back(word);
}
return resVec;
}
};
\ No newline at end of file
/*
* @lc app=leetcode id=1268 lang=cpp
*
* [1268] Search Suggestions System
*/
// @lc code=start
class Solution
{
struct TrieNode
{
TrieNode *next[26];
int isEnd = 0;
TrieNode()
{
for (int i = 0; i < 26; ++i)
next[i] = nullptr;
}
};
TrieNode *root;
vector<vector<string>> res;
public:
vector<vector<string>> suggestedProducts(vector<string> &products, string searchWord)
{
// construct tire by the given list
root = new TrieNode();
for (auto &s : products)
{
TrieNode *node = root;
for (auto ch : s)
{
if (node->next[ch - 'a'] == nullptr)
{
node->next[ch - 'a'] = new TrieNode();
}
node = node->next[ch - 'a'];
}
node->isEnd += 1;
} //end construct trees
TrieNode *node = root;
string word;
for (int i = 0; i < searchWord.size(); i++)
{
char ch = searchWord[i];
if (node->next[ch - 'a'] == nullptr)
{
for (int j = i; j < searchWord.size(); j++)
res.push_back({});
break;
}
node = node->next[ch - 'a'];
word.push_back(ch);
vector<string> list;
string temp = "";
dfs(temp, node, list);
while (list.size() > 3)
list.pop_back();
for (int j = 0; j < list.size(); j++)
list[j] = word + list[j];
res.push_back(list);
}
return res;
}
void
dfs(string curr, TrieNode *node, vector<string> &list)
{
if (node == nullptr)
return;
if (node->isEnd > 0)
{
for (int k = 0; k < node->isEnd && list.size() < 3; k++)
list.push_back(curr);
}
for (int i = 0; i < 26; ++i)
{
if (list.size() > 3)
return;
if (node->next[i] != nullptr)
{
curr.push_back(i + 'a');
dfs(curr, node->next[i], list);
curr.pop_back();
}
}
}
};
// @lc code=end
/*
* @lc app=leetcode id=13 lang=cpp
*
* [13] Roman to Integer
*/
// @lc code=start
class Solution
{
public:
int romanToInt(string s)
{
int res = 0;
for (int i = 0; i < s.size(); ++i)
{
if (s[i] == 'I')
{
if (i + 1 < s.size() && (s[i + 1] == 'V' || s[i + 1] == 'X'))
res -= 1;
else
res += 1;
}
else if (s[i] == 'V')
res += 5;
else if (s[i] == 'X')
{
if (i + 1 < s.size() && (s[i + 1] == 'L' || s[i + 1] == 'C'))
res -= 10;
else
res += 10;
}
else if (s[i] == 'L')
res += 50;
else if (s[i] == 'C')
{
if (i + 1 < s.size() && (s[i + 1] == 'D' || s[i + 1] == 'M'))
res -= 100;
else
res += 100;
}
else if (s[i] == 'D')
res += 500;
else if (s[i] == 'M')
res += 1000;
} //for
return res;
}
};
// @lc code=end
//s = "MCMXCIV"
// i
//
\ No newline at end of file
/*
* @lc app=leetcode id=1353 lang=cpp
*
* [1353] Maximum Number of Events That Can Be Attended
*/
// @lc code=start
class Solution
{
// sort array by the begin day
static bool comp(vector<int> &a, vector<int> &b)
{
if (a[0] != b[0])
return a[0] < b[0];
return a[1] < b[1];
}
struct myComp
{
bool operator()(vector<int> &a, vector<int> &b)
{
return a[1] > b[1];
}
};
public:
// sort + pq + greedy
int maxEvents(vector<vector<int>> &events)
{
sort(events.begin(), events.end(), comp);
priority_queue<vector<int>, vector<vector<int>>, myComp> pq;
const int endDay = 100000;
int currEvent = 0;
int res = 0;
// starting from day
for (int day = 1; day <= endDay && (currEvent != events.size() || !pq.empty()); ++day)
{
while (currEvent < events.size() && events[currEvent][0] == day)
{
pq.push(events[currEvent]);
++currEvent;
}
while (!pq.empty() && pq.top()[1] < day)
pq.pop();
if (!pq.empty())
{
pq.pop();
res++;
}
} //for
return res;
}
};
// @lc code=end
//[[1,2],[2,3],[3,4],[1,2]]
//[1,2], [1,2], [2,3], [3,4]
// pq : [1,2], [2,3]
// day = 2
/*
* @lc app=leetcode id=139 lang=cpp
*
* [139] Word Break
*/
// @lc code=start
class Solution
{
struct TrieNode
{
TrieNode *next[26];
bool isEnd = false;
// contructor
TrieNode()
{
for (int i = 0; i < 26; ++i)
next[i] = nullptr;
}
};
TrieNode *root;
public:
bool wordBreak(string s, vector<string> &wordDict)
{
//* given a dict -> trie
//* dfs + memo
// first, construct trie
root = new TrieNode();
for (auto &word : wordDict)
{
TrieNode *node = root;
for (auto ch : word)
{
if (node->next[ch - 'a'] == nullptr)
node->next[ch - 'a'] = new TrieNode();
node = node->next[ch - 'a'];
}
node->isEnd = true;
} //for
TrieNode *node = root;
//* use memo to record where we got wrong
vector<bool> failed(s.size() + 1, false);
return dfs(0, s, failed);
}
bool dfs(int curr, string &s, vector<bool> &failed)
{
if (failed[curr])
return false;
// at the end, then we are good
if (curr == s.size())
return true;
TrieNode *node = root;
for (int i = curr; i < s.size(); ++i)
{
if (node->next[s[i] - 'a'] != nullptr)
{
node = node->next[s[i] - 'a'];
if (node->isEnd && dfs(i + 1, s, failed))
return true;
}
else
{
failed[curr] = true;
break;
}
}
return false;
}
};
// @lc code=end
/*
* @lc app=leetcode id=140 lang=cpp
*
* [140] Word Break II
*/
// @lc code=start
class Solution
{
class TrieNode
{
public:
TrieNode *next[26];
bool isEnd;
TrieNode()
{
isEnd = false;
for (int i = 0; i < 26; i++)
next[i] = NULL;
}
};
TrieNode *root;
int memo[300];
vector<string> res;
public:
vector<string> wordBreak(string s, vector<string> &wordDict)
{
root = new TrieNode();
for (auto &word : wordDict)
{
TrieNode *node = root;
for (auto ch : word)
{
if (node->next[ch - 'a'] == NULL)
node->next[ch - 'a'] = new TrieNode();
node = node->next[ch - 'a'];
}
node->isEnd = true;
}
vector<string> ans;
dfs(s, 0, ans);
return res;
}
bool dfs(string &s, int cur, vector<string> &ans)
{
if (memo[cur] == 1)
return false;
if (cur == s.size())
{
string t;
for (auto word : ans)
t += word + " ";
t.pop_back();
res.push_back(t);
return true;
}
TrieNode *node = root;
bool flag = false;
for (int i = cur; i < s.size(); i++)
{
if (node->next[s[i] - 'a'] != NULL)
{
node = node->next[s[i] - 'a'];
if (node->isEnd == true)
{
ans.push_back(s.substr(cur, i - cur + 1));
if (dfs(s, i + 1, ans))
flag = true;
ans.pop_back();
}
}
else
{
break;
}
}
if (flag == false)
memo[cur] = 1;
return flag;
}
};
// @lc code=end
/*
* @lc app=leetcode id=166 lang=cpp
*
* [166] Fraction to Recurring Decimal
*/
// @lc code=start
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
int sign = 1;
long a = numerator;
long b = denominator;
if (a < 0)
{
sign *= -1;
a = abs(a);
}
if (b < 0)
{
sign *= -1;
b = abs(b);
}
if (a == 0)
return "0";
string res;
if (sign == -1)
res.push_back('-');
res += to_string(a / b);
long c = a % b;
if (c == 0)
return res;
unordered_map<int, int> map; // reminder, pos of digit
res.push_back('.');
while (c != 0 && map.find(c) == map.end())
{
map[c] = res.size();
int digit = c * 10 / b;
res.push_back(digit + '0');
c = (c * 10) % b;
}
if (c == 0)
return res;
res.insert(res.begin() + map[c], '(');
res.push_back(')');
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=212 lang=cpp
*
* [212] Word Search II
*/
// @lc code=start
class Solution
{
class TrieNode
{
public:
TrieNode *next[26];
bool isEnd;
TrieNode()
{
for (int i = 0; i < 26; i++)
next[i