Commit 046b0899 authored by anqiwa's avatar anqiwa 😲
Browse files

10/6/2021 update

parent 420e8c43
/*
* @lc app=leetcode id=1092 lang=cpp
*
* [1092] Shortest Common Supersequence
*/
// @lc code=start
class Solution
{
public:
string shortestCommonSupersequence(string str1, string str2)
{
}
};
// @lc code=end
/*
* @lc app=leetcode id=1143 lang=cpp
*
* [1143] Longest Common Subsequence
*/
// @lc code=start
class Solution
{
public:
int longestCommonSubsequence(string text1, string text2)
{
const int n = text1.size();
const int m = text2.size();
text1 = '#' + text1;
text2 = '#' + text2;
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (text1[i] == text2[j])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[n][m];
}
};
// abcde
// ace
// LCS: ace = 3
// #abc
// #abc
//
// 0 1 1 1
// 0 1 2 2
// 0 1 2 3
// 0 1 2 3
// define
// dp[i][j] -> the LCS for [0:i] & [0:j] of two given string
// @lc code=end
/*
* @lc app=leetcode id=121 lang=cpp
*
* [121] Best Time to Buy and Sell Stock
*/
// @lc code=start
class Solution
{
public:
int maxProfit(vector<int> &prices)
{
const int n = prices.size();
int hold = INT_MIN;
int sold = 0;
for (int i = 0; i < n; ++i)
{
int old_hold = hold;
int old_sold = sold;
hold = max(old_hold, -prices[i]);
sold = max(old_hold + prices[i], old_sold);
}
return max(hold, sold);
}
};
// @lc code=end
// prices = [7,1,5,3,6,4]
//
// define states:
// 0-> holding max
// 1-> sold max
// dp[i][sold] = max{dp[i-1][hold] + price, dp[i-1][sold]}
// dp[i][hold] = max{dp[i-1][hold], -price}
// i = 0 i = 1
//
//
//
\ No newline at end of file
/*
* @lc app=leetcode id=1284 lang=cpp
*
* [1284] Minimum Number of Flips to Convert Binary Matrix to Zero Matrix
*/
// @lc code=start
class Solution
{
int m, n;
public:
int minFlips(vector<vector<int>> &mat)
{
m = mat.size();
n = mat[0].size();
int res = INT_MAX;
for (int state = 0; state < (1 << (m * n)); state++)
{
if (check(mat, state))
res = min(res, (int)bitset<9>(state).count());
}
if (res == INT_MAX)
return -1;
else
return res;
}
bool check(vector<vector<int>> &mat, int state)
{
auto temp = mat;
auto dir = vector<pair<int, int>>({{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {0, 0}});
for (int s = 0; s < (m * n); s++)
{
int t = state % 2;
state /= 2;
if (t == 0)
continue;
int i = s / n;
int j = s % n;
for (int k = 0; k < 5; k++)
{
int x = i + dir[k].first;
int y = j + dir[k].second;
if (x < 0 || x >= m || y < 0 || y >= n)
continue;
temp[x][y] = 1 - temp[x][y];
}
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (temp[i][j] != 0)
return false;
return true;
}
};
// @lc code=end
/*
* @lc app=leetcode id=1326 lang=cpp
*
* [1326] Minimum Number of Taps to Open to Water a Garden
*/
// @lc code=start
class Solution
{
public:
static bool myComp(array<int, 2> &a, array<int, 2> &b)
{
if (a[0] != b[0])
return a[0] < b[0];
else
return a[1] > b[1];
}
int minTaps(int n, vector<int> &ranges)
{
vector<array<int, 2>> intervals(n + 1);
for (int i = 0; i <= n; ++i)
{
intervals[i] = {i - ranges[i], i + ranges[i]};
}
sort(intervals.begin(), intervals.end(), myComp);
if (intervals[0][0] > 0)
return -1;
int res = 0;
int far = 0;
int i = 0;
while (i < intervals.size())
{
res++;
int nextFar = far;
while (i < intervals.size() && intervals[i][0] <= far)
{
nextFar = max(nextFar, intervals[i][1]);
++i;
}
if (nextFar >= n)
return res;
if (nextFar == far)
return -1;
far = nextFar;
}
return -1;
}
};
// @lc code=end
/*
* @lc app=leetcode id=174 lang=cpp
*
* [174] Dungeon Game
*/
// @lc code=start
class Solution
{
public:
int calculateMinimumHP(vector<vector<int>> &dungeon)
{
//* core: 反向逆推
const int n = dungeon.size();
const int m = dungeon[0].size();
// dp[i][j] -> min hp to be alive after eat the curr
vector<vector<int>> dp(n, vector<int>(m, 1));
for (int i = n - 1; i >= 0; --i)
{
for (int j = m - 1; j >= 0; --j)
{
// alive at most bottom-right
if (i == n - 1 && j == m - 1)
{
dp[i][j] = 1; // need at least one blood to be alive
}
else if (i == n - 1)
{
dp[i][j] = dp[i][j + 1] - dungeon[i][j + 1];
}
else if (j == m - 1)
{
dp[i][j] = dp[i + 1][j] - dungeon[i + 1][j];
}
else //gernal case
{
dp[i][j] = min(dp[i][j + 1] - dungeon[i][j + 1],
dp[i + 1][j] - dungeon[i + 1][j]);
}
dp[i][j] = max(1, dp[i][j]); //* any time, must be alive
}
}
// the first one need to be eaten
dp[0][0] = dp[0][0] - dungeon[0][0];
dp[0][0] = max(dp[0][0], 1);
return dp[0][0];
}
};
// @lc code=end
/*
* @lc app=leetcode id=290 lang=cpp
*
* [290] Word Pattern
*/
// @lc code=start
class Solution
{
public:
bool wordPattern(string pattern, string s)
{
unordered_map<char, string> map1;
unordered_map<string, char> map2;
stringstream ss(s);
int i = 0;
string next;
while (ss >> next)
{
if (i > pattern.size())
return false;
if (map1.find(pattern[i]) != map1.end())
{
if (next != map1[pattern[i]])
return false;
}
else if (map2.find(next) != map2.end())
{
if (pattern[i] != map2[next])
return false;
}
else
{
map1[pattern[i]] = next;
map2[next] = pattern[i];
}
++i;
}
if (i != pattern.size())
return false;
return true;
}
};
// @lc code=end
/*
* @lc app=leetcode id=300 lang=cpp
*
* [300] Longest Increasing Subsequence
*/
// @lc code=start
class Solution
{
public:
int lengthOfLIS(vector<int> &nums)
{
// save by dp: O(n^2), can be better(O(nlogn))
const int n = nums.size();
vector<int> dp(n, 1); //any seq must has length >= 1 (itself)
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < i; ++j)
{
if (nums[j] < nums[i])
dp[i] = max(dp[j] + 1, dp[i]);
}
}
return *max_element(dp.begin(), dp.end());
}
};
// @lc code=endS
// a seq is derived from an array from by adding/ deleting ...
// nums = [10,9,2,5,3,7,101,18]
// [2,3,7,101] -> length of 4
// ith turn, find j in [0...i-1] that is longest but less than nums[i]
//
\ No newline at end of file
/*
* @lc app=leetcode id=442 lang=cpp
*
* [442] Find All Duplicates in an Array
*/
// @lc code=start
class Solution
{
public:
vector<int> findDuplicates(vector<int> &nums)
{
//* indexing sort useful when:
//* 1. <= vals <= n && nums.length == n
//* 2. find missing or duplicate, etc
//* main idea:
//* sort val i to nums[i] as much as possible
int n = nums.size();
nums.insert(nums.begin(), 0);
vector<int> res;
for (int i = 1; i < nums.size(); ++i)
{
while (nums[i] != i &&
nums[nums[i]] != nums[i])
{
swap(nums[i], nums[nums[i]]);
}
} //for
for (int i = 1; i < nums.size(); ++i)
{
if (nums[i] != i)
res.push_back(nums[i]);
}
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=463 lang=cpp
*
* [463] Island Perimeter
*/
// @lc code=start
class Solution
{
public:
int islandPerimeter(vector<vector<int>> &grid)
{
const int n = grid.size();
const int m = grid[0].size();
vector<vector<int>> cnt(n, vector<int>(m, 0));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (grid[i][j] == 1)
{
if (i != 0 && grid[i - 1][j] == 1)
cnt[i][j]++;
if (i != n - 1 && grid[i + 1][j] == 1)
cnt[i][j]++;
if (j != 0 && grid[i][j - 1] == 1)
cnt[i][j]++;
if (j != m - 1 && grid[i][j + 1] == 1)
cnt[i][j]++;
}
}
}
int res = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (grid[i][j] == 1)
res += (4 - cnt[i][j]);
}
}
return res;
}
};
// @lc code=end
//
\ No newline at end of file
/*
* @lc app=leetcode id=547 lang=cpp
*
* [547] Number of Provinces
*/
// @lc code=start
class Solution
{
// 各自的爸爸
unordered_map<int, int> father; // {son i, father of i}
public:
int findCircleNum(vector<vector<int>> &isConnected)
{
//* 此题是 union find 中最经典的应用
//* 务必多复习
const int n = isConnected.size();
// 1. initialze each to be the father of their own
for (int i = 0; i < n; ++i)
father[i] = i;
//2. 遍历 adj matrix 中每个相连关系
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
// if i, j connected
if (i != j && isConnected[i][j])
if (findFather(i) != findFather(j))
union2Grps(i, j);
} //for
} //for
unordered_set<int> ancestors;
for (int i = 0; i < n; ++i)
{
father[i] = findFather(i);
ancestors.insert(father[i]);
}
return ancestors.size();
}
//* find the ancestor of x + path compression
int findFather(int x)
{
if (father[x] == x)
return father[x];
// 如果我自己不是我自己的祖先
// 我爸爸祖先就是我的祖先
// * path compression
father[x] = findFather(father[x]);
return father[x];
}
//* union two group together via edge(i,j)
void union2Grps(int i, int j)
{
i = findFather(i);
j = findFather(j);
if (i <= j)
father[j] = i;
else
father[i] = j;
}
};
// @lc code=end
/*
* @lc app=leetcode id=673 lang=cpp
*
* [673] Number of Longest Increasing Subsequence
*/
// @lc code=start
class Solution
{
public:
int findNumberOfLIS(vector<int> &nums)
{
const int n = nums.size();
//{dp[i] = {length of LIS by i}}
vector<int> dp(n, 1);
vector<int> times(n, 1); // ways to reach ith point
for (int i = 1; i < n; ++i)
{
int maxNum = 1;
for (int j = 0; j < i; j++)
{
if (nums[i] > nums[j])
{
if (dp[j] + 1 > dp[i]) // if len increased
{
dp[i] = dp[j] + 1;
maxNum = times[j];
}
//if len unchanged and other j match this curr max length
else if (dp[j] + 1 == dp[i])
{
maxNum += times[j]; // accumuate the times to reach there
}
}
}
// update len and times
times[i] = maxNum;
}
int maxLen = 1;
int maxNum = 0;
for (int i = 0; i < n; i++)
{
if (dp[i] > maxLen)
{
maxLen = dp[i];
maxNum = times[i];
}
else if (dp[i] == maxLen)
maxNum += times[i];
}
return maxNum;
}
};
// @lc code=end
// return the number of LIS
// [1, 3, 5, 4, 7]
// i
// j
//dp 1 2 3 1 1
//ti 1 1 1 1 1
// 1-> 3-> 4 ->7
// 1-> 3-> 5-> 7
//2 ways to get 7
// also record how many ways to reach this pt?