Commit adad553e authored by anqiwa's avatar anqiwa 😲
Browse files

update 10/19

parent 046b0899
class Solution
{
public:
unordered_map<int, int> groups; //{v, group}
static bool mycomp(vector<int> &a, vector<int> &b)
{
if (a[2] != b[2])
return a[2] < b[2];
return true;
}
int minimumCost(int n, vector<vector<int>> &connections)
{
const int E = connections.size();
int cost = 0;
int numEdge = 0;
// Kruskal(greedy + union-find)
// 1. sort all the given edges by cost asc + init groups
sort(connections.begin(), connections.end(), mycomp);
for (int i = 1; i <= n; ++i)
groups[i] = i;
for (int i = 0; i < E; ++i)
{
int v1 = connections[i][0];
int v2 = connections[i][1];
int edgeCost = connections[i][2];
// if not int a group(not connected)
if (find(v1) != find(v2))
{
unionfiy(v1, v2);
cost += edgeCost;
numEdge++;
}
if (numEdge == n - 1)
return cost;
}
for (int i = 1; i <= n; i++)
{
if (find(i) != find(i - 1))
return -1;
}
return cost;
}
int find(int i)
{
if (groups[i] == i)
return i;
else
// path compression
groups[i] = find(groups[i]);
return groups[i];
}
void unionfiy(int i, int j)
{
int x = find(i);
int y = find(j);
groups[x] = y;
}
};
// connections[i] = (xi, yi, cost_i);
// return the min cost of connecting all n cities
// if impossible to connect return -1
// MST
// Kruskal
/*
* @lc app=leetcode id=14 lang=cpp
*
* [14] Longest Common Prefix
*/
// @lc code=start
class Solution
{
public:
string longestCommonPrefix(vector<string> &strs)
{
string prefix = "";
int minlen = 201;
int n = strs.size();
for (auto &s : strs)
{
minlen = min(minlen, (int)s.size());
}
for (int i = 0; i < minlen; ++i)
{
for (int j = 0; j < n; ++j)
{
if (strs[j][i] != strs[0][i])
return prefix;
}
prefix.push_back(strs[0][i]);
}
return prefix;
}
};
// @lc code=end
/*
* @lc app=leetcode id=1481 lang=cpp
*
* [1481] Least Number of Unique Integers after K Removals
*/
// @lc code=start
class Solution
{
public:
int findLeastNumOfUniqueInts(vector<int> &arr, int k)
{
// greedy + pq
const int n = arr.size();
int totalElts = 0;
unordered_map<int, int> cnts;
for (int i = 0; i < n; ++i)
{
cnts[arr[i]]++;
} //for
totalElts = cnts.size();
// reverse key and val, put into a vector
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
for (auto &p : cnts)
{
pq.push({p.second, p.first});
} //for
int numRemoval = 0;
while (!pq.empty() && k > 0)
{
int cnt = pq.top().first;
int ele = pq.top().second;
pq.pop();
if (k >= cnt)
{
k -= cnt;
++numRemoval;
}
} //while
return totalElts - numRemoval;
}
};
// @lc code=end
// [5, 5, 4]
// given an arr and int k
// find least 3 of unique int after remove
// exact k element
// greedy??
//least # of unique -> remove most unique
// 4,3,1,2
// 1 3 2 1
// 4, 2, 1, 3
// 1, 1, 2, 3
/*
* @lc app=leetcode id=1492 lang=cpp
*
* [1492] The kth Factor of n
*/
// @lc code=start
class Solution
{
public:
int kthFactor(int n, int k)
{
int cnt = 0;
int i = 1;
for (; i <= n; ++i)
{
if (n % i == 0)
cnt++;
if (cnt == k)
return i;
}
return -1;
}
};
// @lc code=end
//two int(+) n , k
// i where n%i==0, than i is a factor of
//return kth factor in list
// n = 12, k =3
//1,2,3,4,6,12
// all factors are in the range of [1,n]
/*
* @lc app=leetcode id=1905 lang=cpp
*
* [1905] Count Sub Islands
*/
// @lc code=start
class Solution
{
int res = 0;
int m = 0;
int n = 0;
vector<pair<int, int>> dirs = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
public:
int countSubIslands(vector<vector<int>> &grid1, vector<vector<int>> &grid2)
{
//* 这道题的难点是: 即便遇到了点在grid1中不为 1,我们也要把grid2的岛走完,不然会重复计算
// find the first 1 int grid2
this->m = grid2.size();
this->n = grid2[0].size();
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (grid2[i][j] == 1)
bfs(i, j, grid1, grid2);
} //for
} // for
return res;
}
void bfs(int i, int j, vector<vector<int>> &grid1,
vector<vector<int>> &grid2)
{
queue<pair<int, int>> q;
grid2[i][j] = -1;
q.push({i, j});
bool flag = grid1[i][j] == 1;
while (!q.empty())
{
int curr_x = q.front().first;
int curr_y = q.front().second;
q.pop();
for (auto &dir : dirs)
{
int next_x = curr_x + dir.first;
int next_y = curr_y + dir.second;
if (next_x < 0 || next_y < 0 || next_x >= m || next_y >= n)
continue;
if (grid2[next_x][next_y] == -1)
continue;
if (grid2[next_x][next_y] == 1)
{
if (grid1[next_x][next_y] != 1)
{
flag = false;
}
grid2[next_x][next_y] = -1;
q.push({next_x, next_y});
}
} //for
} //while
if (flag)
res++;
}
};
// @lc code=end
//
// bfs to find islands in grid2
\ No newline at end of file
/*
* @lc app=leetcode id=208 lang=cpp
*
* [208] Implement Trie (Prefix Tree)
*/
// @lc code=start
class Trie
{
public:
/** Initialize your data structure here. */
Trie() : root_(new TrieNode()) {}
/** Inserts a word into the trie. */
void insert(const string &word)
{
TrieNode *p = root_.get();
for (const char c : word)
{
if (!p->children[c - 'a'])
p->children[c - 'a'] = new TrieNode();
p = p->children[c - 'a'];
}
p->is_word = true;
}
/** Returns if the word is in the trie. */
bool search(const string &word) const
{
const TrieNode *p = find(word);
return p && p->is_word;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(const string &prefix) const
{
return find(prefix) != nullptr;
}
private:
struct TrieNode
{
TrieNode() : is_word(false), children(26, nullptr) {}
~TrieNode()
{
for (TrieNode *child : children)
if (child)
delete child;
}
bool is_word;
vector<TrieNode *> children;
};
const TrieNode *find(const string &prefix) const
{
const TrieNode *p = root_.get();
for (const char c : prefix)
{
p = p->children[c - 'a'];
if (p == nullptr)
break;
}
return p;
}
std::unique_ptr<TrieNode> root_;
};
/**
* 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);
*/
// @lc code=end
/*
* @lc app=leetcode id=287 lang=cpp
*
* [287] Find the Duplicate Number
*/
// @lc code=start
class Solution
{
public:
int findDuplicate(vector<int> &nums)
{
// fast-slow ptr
// very hard to think of
int slow = nums[0];
int fast = nums[nums[0]];
while (slow != fast)
{
slow = nums[slow];
fast = nums[nums[fast]];
} //while
fast = 0;
while (slow != fast)
{
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
};
// @lc code=end
// nums = [ 1, 3, 4, 2, 2 ] n+1 numbers in range [1,n]
// output = 2
/*
* @lc app=leetcode id=374 lang=cpp
*
* [374] Guess Number Higher or Lower
*/
// @lc code=start
/**
* Forward declaration of guess API.
* @param num your guess
* @return -1 if num is lower than the guess number
* 1 if num is higher than the guess number
* otherwise return 0
* int guess(int num);
*/
class Solution
{
public:
int guessNumber(int n)
{
int l = 1;
int r = n; // must inclusive on so not overflow the int
int mid = l;
while (l <= r)
{
mid = l + (r - l) / 2;
int g = guess(mid);
cout << g << endl;
if (g < 0)
{
r = mid;
}
else if (g > 0)
{
l = mid + 1;
}
else
{
return mid;
}
} //while
return l;
}
};
// @lc code=end
// 2 guess 1
// l = 1; r = 3
// mid == 2
// r = 2 l = 1;
// mid = 1
// 1 2
// l r
/*
* @lc app=leetcode id=387 lang=cpp
*
* [387] First Unique Character in a String
*/
// @lc code=start
class Solution
{
public:
int firstUniqChar(string s)
{
const int n = s.size();
unordered_map<char, int> cnt;
for (int i = 0; i < n; ++i)
{
cnt[s[i]]++;
}
for (int j = 0; j < n; ++j)
{
if (cnt[s[j]] == 1)
return j;
}
return -1;
}
};
// @lc code=end
/*
* @lc app=leetcode id=49 lang=cpp
*
* [49] Group Anagrams
*/
// @lc code=start
class Solution
{
public:
vector<vector<string>> groupAnagrams(vector<string> &strs)
{
const int n = strs.size();
vector<vector<string>> res;
unordered_map<string, vector<string>> map;
for (int i = 0; i < n; ++i)
{
string s = strs[i];
sort(s.begin(), s.end());
map[s].push_back(strs[i]);
} //for
//key,val pair
for (auto list : map)
{
res.push_back(list.second);
}
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=518 lang=cpp
*
* [518] Coin Change 2
*/
// @lc code=start
class Solution
{
public:
int change(int amount, vector<int> &coins)
{
// 这道题看起来很像dfs 但是其实是背包型dp的一种
// 核心是 coins【i】可以取 0~k 次, where k = amount/coin【i】
// 这里capacity 为 amount
// amount can be 0 ~ amount, amount+1 possiblilities
// dp[c] <- combination to reach c
vector<int> dp(amount + 1, 0);
dp[0] = 1;
// like 0/1 knapsack problem
for (int i = 0; i < coins.size(); ++i)
{
for (int c = 1; c <= amount; ++c)
{
if (c >= coins[i])
dp[c] += dp[c - coins[i]];
} //for
} //for
return dp[amount];
}
};
// @lc code=end
// amount = 5
// [1,2,5]
// i
// c = 4
//dp[(c-2)]
\ No newline at end of file
/*
* @lc app=leetcode id=55 lang=cpp
*
* [55] Jump Game
*/
// @lc code=start
class Solution
{
public:
bool canJump(vector<int> &nums)
{
}
};
// @lc code=end
// each element is max jump length
// nums = [2,3,1,1,4]
//
\ No newline at end of file
/*
* @lc app=leetcode id=56 lang=cpp
*
* [56] Merge Intervals
*/
// @lc code=start
class Solution
{
static bool comp(pair<int, int> &a, pair<int, int> &b)
{
if (a.first != b.first)
return a.first < b.first;
// --------
// ----
// --
// this is ok, as cnt never turn to be 0 in the middle
return a.second > b.second;
}
public:
vector<vector<int>> merge(vector<vector<int>> &intervals)
{
// 扫描线思维
// 1 {start,1}, {end,-1}
// 2 sort
// 3 use cnt to record # of curr overlapping
// 4 a interval merged interval lifetime:
// cnt = 0 -> cnt = 1 -> cnt = 2 ... -> cnt = 1 -> cnt = 0
// thus, when cnt = 1, new interval begin
// when when cnt back to 0, this interval end + push into res
vector<vector<int>> res;
vector<pair<int, int>> times;
for (int i = 0; i < intervals.size(); ++i)
{
times.push_back({intervals[i][0], 1});