// 76. Minimum Window Substring
string minWindow(string s, string t) {
unordered_map<char, int> cnt;
unordered_set<char> ts;
for (const auto& c:t) {
--cnt[c];
ts.insert(c);
}
int diff = cnt.size();
int res = INT_MAX;
int stt_idx = 0;
for (int i = 0, j = 0; i < s.size(); ++i) {
++cnt[s[i]];
if (ts.count(s[i])) {
if (!cnt[s[i]]) {
--diff;
}
while(!ts.count(s[j]) ||
(ts.count(s[j]) && cnt[s[j]] > 0)) {
--cnt[s[j]];
++j;
}
}
if (!diff) {
if (i - j + 1 < res) {
res = i - j + 1;
stt_idx = j;
}
}
}
return res == INT_MAX?"":s.substr(stt_idx, res);
}
// Verify if two line segment intersect
// https://www.cnblogs.com/kane1990/p/5742830.html
// 456. 132 Pattern
bool find132pattern(vector<int>& nums) {
stack<int> stk;
int right = INT_MIN;
for (auto it = nums.rbegin(); it != nums.rend(); ++it) {
if (*it < right) return true;
while (!stk.empty() && stk.top() < *it) {
right = stk.top();
stk.pop();
}
stk.push(*it);
}
return false;
}
// 535. Encode and Decode TinyURL
unordered_map<string, string> longToShort;
unordered_map<string, string> shortToLong;
int num_codes = 7;
string codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Encodes a URL to a shortened URL.
string encode(string longUrl) {
bool hasCode = true;
string shortUrl = "";
while(hasCode) {
int c_ind = 62*rand() % 61;
shortUrl += codes[c_ind];
if(shortUrl.size()==num_codes) {
if(shortToLong.find(shortUrl)!=shortToLong.end()) {
shortUrl = "";
}
else {
hasCode = false;
}
}
}
longToShort[longUrl] = shortUrl;
shortToLong[shortUrl] = longUrl;
return shortUrl;
}
// Decodes a shortened URL to its original URL.
string decode(string shortUrl) {
return shortToLong[shortUrl];
}
};
// 121. Best Time to Buy and Sell Stock
int maxProfit(vector<int>& prices) {
int buy = prices[0];
int p = 0;
for (int i = 1; i < prices.size(); ++i) {
if (prices[i] > buy) {
p = max(p, prices[i] - buy);
} else {
buy = prices[i];
}
}
return p;
}
// Clean solution
int MaxProfit(const vector<int>& nums) {
int profit = 0;
for (int i = 0, min_p = INT_MAX; i < nums.size(); ++i) {
profit = max(profit, nums[i] - min_p);
min_p = min(nums[i], min_p);
}
return profit;
}
// 122. Best Time to Buy and Sell Stock II
int maxProfit(vector<int>& prices) {
int profit = 0;
for (int i = 0; i + 1< prices.size(); ++i) {
profit += max(0, prices[i+1] - prices[i]);
}
return profit;
}
// 123. Best Time to Buy and Sell Stock III
// f(i) = p(i) - min_p
// = f(i-1)
// 前后缀分解
int maxProfit(vector<int>& prices) {
vector<int> f(prices.size()+2, 0);
for (int i = 1, min_p = INT_MAX; i <= prices.size(); ++i) {
f[i] = max(f[i-1], prices[i-1]-min_p);
min_p = min(min_p, prices[i-1]);
}
int res = 0;
for (int i = prices.size(), max_p = 0;
i >= 1; --i) {
res = max(res, f[i-1] + max_p - prices[i-1]);
max_p = max(prices[i-1], max_p);
}
return res;
}
// 188. Best Time to Buy and Sell Stock IV
// state machine DP
// 0(no buy stock) 1(buy stock)
int maxProfit(int k, vector<int>& prices) {
const int INF = -1e8;
const int size = prices.size();
if (k >= size/2) {
int res = 0;
for (int i = 1; i < prices.size(); ++i) {
res += max(0, prices[i] - prices[i-1]);
}
return res;
}
vector<vector<int>> f(size+1, vector<int>(k+1, INF));
auto g = f;
int res = 0;
f[0][0] = 0;
for (int i = 1; i <= size; ++i) {
for (int j = 0; j <= k; ++j) {
f[i][j] = max(f[i-1][j], g[i-1][j] + prices[i-1]);
g[i][j] = g[i-1][j];
if (j) g[i][j] = max(g[i][j], f[i-1][j-1] - prices[i-1]);
res = max(res, f[i][j]);
}
}
return res;
}
// Optimization
int maxProfit(int k, vector<int>& prices) {
const int INF = -1e8;
const int size = prices.size();
if (k >= size/2) {
int res = 0;
for (int i = 1; i < prices.size(); ++i) {
res += max(0, prices[i] - prices[i-1]);
}
return res;
}
vector<vector<int>> f(2, vector<int>(k+1, INF));
auto g = f;
int res = 0;
f[0][0] = 0;
for (int i = 1; i <= size; ++i) {
for (int j = 0; j <= k; ++j) {
f[i & 1][j] = max(f[i-1 & 1][j], g[i-1 & 1][j] + prices[i-1]);
g[i & 1][j] = g[i-1 & 1][j];
if (j) g[i & 1][j] = max(g[i & 1][j], f[i-1 & 1][j-1] - prices[i-1]);
res = max(res, f[i & 1][j]);
}
}
return res;
}
// 91. Decode Ways
int numDecodings(string s) {
int m = s.length();
if (m == 0) return 0;
if (s[0] == '0') return 0;
vector<int> cnt(m + 1, 0);
cnt[0] = 1;
cnt[1] = 1;
for (int i = 1; i < m; ++i) {
// check if 0 is the valid num
if (s[i] == '0') {
if (!is_valid_num(s[i - 1], s[i])) return 0;
else cnt[i + 1] = cnt[i - 1];
} else {
cnt[i + 1] += cnt[i];
if (is_valid_num(s[i - 1], s[i])) cnt[i + 1] += cnt[i - 1];
}
}
return cnt[m];
}
bool is_valid_num(char& a, char& b) {
if (a == '1' || a == '2' && b < '7') return true;
return false;
}
// Implement vector class
// Self implementation of the Vector Class in C++
#include <bits/stdc++.h>
using namespace std;
template <typename T>
class vectorClass {
private:
// arr is the integer pointer
// which stores the address of our vector
T* arr;
// capacity is the total storage
// capacity of the vector
int capacity;
// current is the number of elements
// currently present in the vector
int current;
public:
// Default constructor to initialise
// an initial capacity of 1 element and
// allocating storage using dynamic allocation
vectorClass() {
arr = new T[1];
capacity = 1;
current = 0;
}
// Function to add an element at the last
void push(T data) {
// if the number of elements is equal to the
// capacity, that means we don't have space to
// accommodate more elements. We need to double the
// capacity
if (current == capacity) {
T* temp = new T[2 * capacity];
// copying old array elements to new array
for (int i = 0; i < capacity; i++) {
temp[i] = arr[i];
}
// deleting previous array
delete[] arr;
capacity *= 2;
arr = temp;
}
// Inserting data
arr[current] = data;
current++;
}
// function to add element at any index
void push(int data, int index) {
// if index is equal to capacity then this
// function is same as push defined above
if (index == capacity)
push(data);
else
arr[index] = data;
}
// function to extract element at any index
T get(int index) {
// if index is within the range
if (index < current)
return arr[index];
}
// function to delete last element
void pop() { current--; }
// function to get size of the vector
int size() { return current; }
// function to get capacity of the vector
int getcapacity() { return capacity; }
// function to print array elements
void print()
{
for (int i = 0; i < current; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
};
// Driver code
int main() {
vectorClass<int> v;
vectorClass<char> v1;
v.push(10);
v.push(20);
v.push(30);
v.push(40);
v.push(50);
v1.push(71);
v1.push(72);
v1.push(73);
v1.push(74);
cout << "Vector size : " << v.size() << endl;
cout << "Vector capacity : " << v.getcapacity() << endl;
cout << "Vector elements : ";
v.print();
v.push(100, 1);
cout << "\nAfter updating 1st index" << endl;
cout << "Vector elements of type int : " << endl;
v.print();
// This was possible because we used templates
cout << "Vector elements of type char : " << endl;
v1.print();
cout << "Element at 1st index of type int: " << v.get(1)
<< endl;
cout << "Element at 1st index of type char: "
<< v1.get(1) << endl;
v.pop();
v1.pop();
cout << "\nAfter deleting last element" << endl;
cout << "Vector size of type int: " << v.size() << endl;
cout << "Vector size of type char: " << v1.size()
<< endl;
cout << "Vector capacity of type int : "
<< v.getcapacity() << endl;
cout << "Vector capacity of type char : "
<< v1.getcapacity() << endl;
cout << "Vector elements of type int: ";
v.print();
cout << "Vector elements of type char: ";
v1.print();
return 0;
}
// LRU cache
class LRUCache {
public:
unordered_map<int, pair<int, list<int>::iterator>> record_;
list<int> key_;
int capacity_ = 0;
LRUCache(int capacity) {
capacity_ = capacity;
}
int get(int key) {
auto it = record_.find(key);
if (it == record_.end()) return -1;
const auto value = it->second;
record_.erase(it);
key_.erase(value.second);
key_.push_front(key);
record_[key] = make_pair(value.first, key_.begin());
return value.first;
}
void put(int key, int value) {
auto it = record_.find(key);
if (it != record_.end()) {
const auto [_, it_list] = it->second;
record_.erase(it);
key_.erase(it_list);
}
if (key_.size() >= capacity_) {
auto back_it = prev(key_.end());
record_.erase(*back_it);
key_.erase(back_it);
}
key_.push_front(key);
record_[key] = std::make_pair(value, key_.begin());
}
};
// reverse bits in a byte.
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
int power = 31;
while (n > 0) {
res |= (n & 1) << power;
--power;
n = n >> 1;
}
return res;
}
// Shift by 16, 8, 4, 2, 1 bits.
// fabonacci number.
// https://www.huaweicloud.com/articles/8359906.html
// 57. Insert Interval
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
auto low_it = lower_bound(begin(intervals), end(intervals), newInterval, [](
const vector<int>& v1, const vector<int>& v2) {
return v1[1] < v2[0];
});
auto high_it = upper_bound(begin(intervals), end(intervals), newInterval, [](
const vector<int>& v1, const vector<int>& v2) {
return v1[1] < v2[0];
});
if (low_it == high_it) {
intervals.insert(low_it, newInterval);
} else {
--high_it;
(*high_it)[0] = min((*low_it)[0], newInterval[0]);
(*high_it)[1] = max((*high_it)[1], newInterval[1]);
intervals.erase(low_it, high_it);
}
return intervals;
}
// 矩阵迷宫start走到end,中间有路障,和金币,要求吃到所有金币,有多少种走法?backtracking.
// 5. Longest Palindromic Substring
string longestPalindrome(string s) {
string ans;
int s_len = s.size();
if(!s_len)
return s;
vector<vector<bool>> rec(s_len, vector<bool>(s_len, 0));
for(int len = 1; len <= s_len; len++) {
for(int ind = 0; ind<=s_len-len; ind++) {
int ind2 = ind+len-1;
rec[ind][ind2] = s[ind]==s[ind2] && (len==1 || len==2 || rec[ind+1][ind2-1]);
if(rec[ind][ind2] && ans.size()<len)
ans = s.substr(ind, len);
}
}
return ans;
}
// Expanding center
string longestPalindrome(string s) {
int slen = s.length();
string res;
if(!slen) return res;
int max_cnt = 1;
res = s[0];
for(int i = 0; i < slen; i++) {
int ind1 = i, ind2 = i;
int cnt = -1;
while(1) {
if(s[ind1] == s[ind2]) cnt += 2;
else break;
ind1--; ind2++;
if(ind1 < 0 || ind2 >= slen) break;
}
if(cnt > max_cnt){
ind1 = ind1 + 1;
max_cnt = cnt; res = s.substr(ind1, max_cnt);
}
}
for(int i = 0; i < slen-1; i++) {
int ind1 = i, ind2 = i+1;
int cnt = 0;
while(1) {
if(s[ind1] == s[ind2]) cnt += 2;
else break;
ind1--; ind2++;
if(ind1 < 0 || ind2 >= slen) break;
}
if(cnt > max_cnt) {
ind1 = ind1 + 1;
max_cnt = cnt; res = s.substr(ind1, max_cnt);
}
}
return res;
}
// 826. Most Profit Assigning Work
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
vector<vector<int>> tasks;
for (int i = 0; i < difficulty.size(); ++i) {
tasks.emplace_back(vector<int>({difficulty[i], profit[i]}));
}
sort(begin(tasks), end(tasks));
sort(begin(worker), end(worker));
int max_profit = 0;
int ttl_profit = 0;
for (int i = 0, j = 0; i < worker.size(); ++i) {
while (j < tasks.size() && worker[i] >= tasks[j][0]) {
max_profit = max(max_profit, tasks[j][1]);
++j;
}
ttl_profit += max_profit;
}
return ttl_profit;
}
// 74. Search a 2D Matrix
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (target < matrix[0][0] || target > matrix.back().back())
return false;
vector<int> column;
for (int i = 0; i < matrix.size(); ++i) {
column.emplace_back(matrix[i][0]);
}
auto it = lower_bound(begin(column), end(column), target);
if (it == end(column) || (*it > target && it != begin(column)))
--it;
const int idx = it - begin(column);
it = lower_bound(begin(matrix[idx]), end(matrix[idx]), target);
return it != end(matrix[idx]) && *it == target;
}
// https://leetcode.com/problems/max-points-on-a-line/
// 149. Max Points on a Line
bool SameLine(const vector<int>& p1,
const vector<int>& p2,
const vector<int>& p3) {
const int p21_x = p2[1] - p1[1];
const int p21_y = p2[0] - p1[0];
const int p31_x = p3[1] - p1[1];
const int p31_y = p3[0] - p1[0];
return p21_x * p31_y == p21_y * p31_x;
}
int maxPoints(vector<vector<int>>& points) {
int res = 1;
for (int i = 0; i < points.size(); ++i) {
for (int j = i + 1; j < points.size(); ++j) {
int cur_len = 2;
for (int k = j + 1; k < points.size(); ++k) {
if (SameLine(points[i], points[j], points[k])) {
++cur_len;
}
}
res = max(res, cur_len);
}
}
return res;
}
// 2 max points
int maxPoints(vector<vector<int>>& points) {
int res = 0;
for (const auto& p:points) {
int ss = 0;
int vs = 0;
unordered_map<long double, int> record;
for (const auto& q: points) {
if (p == q) ++ss;
else if (p[0] == q[0]) ++vs;
else {
++record[static_cast<long double>(p[1] - q[1]) / (p[0] - q[0])];
}
}
const auto data = {vs + ss, res};
res = *max_element(begin(data), end(data));
for (const auto& [k, t] : record) {
res = max(res, t + ss);
}
}
return res;
}
// 1275. Find Winner on a Tic Tac Toe Game
string tictactoe(vector<vector<int>>& moves) {
vector<vector<int>> record(8, vector<int>(2, 0));
int is_a = 0;
for (const auto& m : moves) {
++record[m[0]][is_a];
++record[m[1]+3][is_a];
if (m[0] == m[1])
++record[6][is_a];
if (m[0] + m[1] == 2)
++record[7][is_a];
is_a = 1 - is_a;
}
for (int i = 0; i < 8; ++i) {
if (record[i][0] == 3)
return "A";
if (record[i][1] == 3)
return "B";
}
return moves.size() == 9?"Draw":"Pending";
}
// 794. Valid Tic-Tac-Toe State
bool validTicTacToe(vector<string>& board) {
int X_num = 0;
int O_num = 0;
int state[8][2] = {0};
for (int ind1=0; ind1<3; ind1++) {
for (int ind2=0; ind2<3; ind2++) {
if (board[ind1][ind2]=='X') {
state[ind1][0]++;
state[ind2+3][0]++;
if (ind1==ind2)
state[6][0]++;
if (ind1+ind2==2)
state[7][0]++;
X_num++;
}
else if(board[ind1][ind2]=='O'){
state[ind1][1]++;
state[ind2+3][1]++;
if (ind1==ind2)
state[6][1]++;
if (ind1+ind2==2)
state[7][1]++;
O_num++;
}
}
}
if ((X_num != O_num && X_num != O_num+1))
return false;
int is_end_x = 0;
int is_end_o = 0;
for (int ind2=0; ind2<8; ind2++) {
if (state[ind2][0]==3)
s_end_x++;
if (state[ind2][1]==3)
is_end_o++;
}
if (is_end_x > 0 && is_end_o > 0)
return false;
if (!is_end_o && X_num-O_num==1)
return true;
if (!is_end_x && X_num==O_num)
return true;
return false; // is_end_x<=2 && is_end_o <=2;
}
// 348. Design Tic-Tac-Toe
class TicTacToe {
private:
vector<int> rec1_;
vector<int> rec2_;
int size_;
public:
/** Initialize your data structure here. */
TicTacToe(int n) {
rec1_ = vector<int>((n<<1)+2,0);
rec2 = vector<int>((n<<1)+2,0);
size_ = n;
}
/** Player {player} makes a move at ({row}, {col}).
@param row The row of the board.
@param col The column of the board.
@param player The player, can be either 1 or 2.
@return The current winning condition, can be either:
0: No one wins.
1: Player 1 wins.
2: Player 2 wins. */
int move(int row, int col, int player) {
vector<int> &rec = (player==1)?rec1_:rec2_;
rec[row]++;
rec[col+size_]++;
if(col==row)
rec[size_<<1]++;
if(col+row==size_-1)
rec[(size_<<1) + 1]++;
if(rec[row]==size_ ||
rec[col+size_]==size_ ||
rec[size_<<1] == size_ ||
rec[(size_<<1) + 1] == size_)
return player;
return 0;
}
};
For the projects, see the DL/ML summary; CUDA summary; multi-threading.
// uni-value tree
// 965. Univalued Binary Tree
bool isUnivalTree(TreeNode* root, const int val = 100) {
if (!root) return true;
if (val != 100 && root->val != val) return false;
return isUnivalTree(root->left, root->val) && isUnivalTree(root->right, root->val);
}
// 链表有随机节点的那个
// 138. Copy List with Random Pointer
Node* copyRandomList(Node* head) {
unordered_map<Node*, Node*> record;
record[nullptr] = nullptr;
Node* new_head = new Node(0);
auto copy_cur = new_head;
auto cur = head;
while (cur) {
copy_cur->next = new Node(cur->val);
copy_cur = copy_cur->next;
record[cur] = copy_cur;
cur = cur->next;
}
cur = head;
copy_cur = new_head->next;
while (cur) {
copy_cur->random = record[cur->random];
copy_cur = copy_cur->next;
cur = cur->next;
}
return new_head->next;
}
// 问了如何check一个点在一个长方形内,给提供长方形四个点坐标
// 问了如何check两个长方形有相交
// https://blog.csdn.net/weixin_43619346/article/details/107513919
// 几何题给一个多段线段首尾相连组成的折线段,比如AB,BC,CD, 分割成等距离的k段,找到所有分段点的坐标。题目挺直白的,顺利做出来了。
// 向量,根据比例给值
// 168. Excel Sheet Column Title
string convertToTitle(int n) {
string rel;
while(n > 0) {
int n1 = (n-1)/26;
int n2 = (n-1)%26;
n = n1;
rel = char(n2 + 'A') + rel;
}
return rel;
}
// 八皇后
// 51. N-Queens
static constexpr int kNum = 10;
char kQueen[kNum][kNum];
bool row[kNum] = {false};
bool col[kNum] = {false};
bool dg[2*kNum] = {false};
bool udg[2*kNum] = {false};
void StoreResult(const int N, vector<vector<string>>& ans) {
vector<string> sol;
for (int i = 0; i < N; ++i) {
string tmp;
for (int j = 0; j < N; ++j) {
tmp += kQueen[i][j];
}
sol.push_back(tmp);
}
ans.push_back(sol);
}
void DFS(int x, int y,
const int n, const int N,
vector<vector<string>>& ans) {
if (n > N) return;
if (y == N) {
y = 0;
++x;
}
if (x == N) {
if (n == N) {
StoreResult(N, ans);
}
return;
}
kQueen[x][y] = '.';
DFS(x, y+1, n, N, ans);
if (!row[y] && !col[x] && !dg[x+y] && !udg[-y+x+N]) {
row[y] = col[x] = dg[x+y] = udg[-y+x+N] = true;
kQueen[x][y] = 'Q';
DFS(x, y + 1, n+1, N, ans);
row[y] = col[x] = dg[x+y] = udg[-y+x+N] = false;
kQueen[x][y] = '.';
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ans;
DFS(0, 0, 0, n, ans);
return ans;
}
// 719. Find K-th Smallest Pair Distance
// binary search + sliding window
int Check(const int num, const vector<int>& nums) {
int res = 0;
for (int i = 0, j = 0; i < nums.size(); ++i) {
while (nums[i] - nums[j] > num)
++j;
res += i - j;
}
return res;
}
int smallestDistancePair(vector<int>& nums, int k) {
sort(begin(nums), end(nums));
int l = 0;
int r = nums.back() - nums[0];
while (l + 1 < r) {
const int mid = l + (r - l)/2;
if (Check(mid, nums) >= k) {
r = mid;
} else {
l = mid;
}
}
if (Check(l, nums) >= k) return l;
return r;
}
// priority_queue, Time exceeded.
struct Compare {
bool operator()(const vector<int>& v1, const vector<int>& v2) {
return v1[0] > v2[0];
}
};
int smallestDistancePair(vector<int>& nums_init, int k) {
map<int, int> record;
for (const auto& num : nums_init)
++record[num];
vector<int> nums;
// diff, stt_idx, len
priority_queue<vector<int>, vector<vector<int>>, Compare> pq;
for (const auto& [k, count] : record) {
nums.emplace_back(k);
}
for (int i = 0; i < nums.size(); ++i) {
if (record[nums[i]] > 1) {
const auto count = record[nums[i]];
pq.push({0, i, 0, count * (count - 1) / 2});
} else if (i+1 < nums.size()) {
pq.push({nums[i+1] - nums[i], i, 1, record[nums[i+1]]*record[nums[i]]});
}
}
--k;
while (k > 0) {
const auto tp = pq.top();
k -= tp[3];
if (k < 0) {
return tp[0];
}
pq.pop();
if (tp[1]+tp[2]+1 < nums.size()) {
pq.push({nums[tp[1]+tp[2]+1] - nums[tp[1]], tp[1], tp[2]+1,
record[nums[tp[1]+tp[2]+1]] * record[nums[tp[1]]]});
}
}
return pq.top()[0];
}
// 826. Most Profit Assigning Work
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
vector<vector<int>> tasks;
for (int i = 0; i < difficulty.size(); ++i) {
tasks.emplace_back(vector<int>({difficulty[i], profit[i]}));
}
sort(begin(tasks), end(tasks));
sort(begin(worker), end(worker));
int max_profit = 0;
int ttl_profit = 0;
for (int i = 0, j = 0; i < worker.size(); ++i) {
while (j < tasks.size() && worker[i] >= tasks[j][0]) {
max_profit = max(max_profit, tasks[j][1]);
++j;
}
ttl_profit += max_profit;
}
return ttl_profit;
}
// subset的 找不重复的子集
// 78. Subsets
vector<vector<int>> sub_sets_;
void GetAllSubSets(const vector<int>& nums, const int idx,
vector<int> cur_vec) {
if (idx >= nums.size()) return;
GetAllSubSets(nums, idx + 1, cur_vec);
cur_vec.emplace_back(nums[idx]);
sub_sets_.emplace_back(cur_vec);
GetAllSubSets(nums, idx + 1, cur_vec);
}
vector<vector<int>> subsets(vector<int>& nums) {
GetAllSubSets(nums, 0, {});
sub_sets_.push_back({});
return sub_sets_;
}
// 90. Subsets II
vector<vector<int>> sub_sets_;
vector<int> cur_;
void SubSets(const vector<int>& nums, const int idx) {
if (idx >= nums.size()) {
sub_sets_.push_back(cur_);
return;
}
int i = idx + 1;
while (i < nums.size() && nums[i] == nums[idx]) {
++i;
}
for (int j = idx; j <= i; ++j) {
SubSets(nums, i);
cur_.push_back(nums[idx]);
}
for (int j = idx; j <= i; ++j) {
cur_.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(begin(nums), end(nums));
SubSets(nums, 0);
return sub_sets_;
}
// 矩阵迷宫start走到end,中间有路障,和金币,要求吃到所有金币,有多少种走法?一开始用iteration DFS,后来发现需要用backtrack
// https://blog.csdn.net/ProLayman/article/details/96325387
// Geometry
ML/DL preparation. http://usa.baidu.com/careers/?gh_jid=3048306
For the coding part, see the below:
// 149. Max points on a Line
bool SameLine(const vector<int>& p1,
const vector<int>& p2,
const vector<int>& p3) {
const int p21_x = p2[1] - p1[1];
const int p21_y = p2[0] - p1[0];
const int p31_x = p3[1] - p1[1];
const int p31_y = p3[0] - p1[0];
return p21_x * p31_y == p21_y * p31_x;
}
int maxPoints(vector<vector<int>>& points) {
int res = 1;
for (int i = 0; i < points.size(); ++i) {
for (int j = i + 1; j < points.size(); ++j) {
int cur_len = 2;
for (int k = j + 1; k < points.size(); ++k) {
if (SameLine(points[i], points[j], points[k])) {
++cur_len;
}
}
res = max(res, cur_len);
}
}
return res;
}
// 74. Search in 2D matrix
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (target < matrix[0][0] || target > matrix.back().back())
return false;
vector<int> column;
for (int i = 0; i < matrix.size(); ++i) {
column.emplace_back(matrix[i][0]);
}
auto it = lower_bound(begin(column), end(column), target);
if (it == end(column) || (*it > target && it != begin(column)))
--it;
const int idx = it - begin(column);
it = lower_bound(begin(matrix[idx]), end(matrix[idx]), target);
return it != end(matrix[idx]) && *it == target;
}
// 965. Univalued Binary Tree
bool isUnivalTree(TreeNode* root, const int val = 100) {
if (!root) return true;
if (val != 100 && root->val != val) return false;
return isUnivalTree(root->left, root->val) && isUnivalTree(root->right, root->val);
}
// Leetcode basic calculator series
// 224. Basic Calculator
pair<string, int> Parse(const string& s) {
int new_idx = 0;
stack<int> stk;
int val = 0;
int inc_size = 0;
string res;
string tmp = s;
while (new_idx < tmp.size()) {
if (tmp[new_idx] == '(')
stk.push(new_idx);
else if (tmp[new_idx] == ')') {
const int left = stk.top();
stk.pop();
val = calculate(tmp.substr(left+1, new_idx - left - 1));
const auto new_val = to_string(val);
tmp = tmp.substr(0, left) + new_val + tmp.substr(new_idx + 1);
const int tmp_inc_size = new_idx - left + 1 - new_val.size();
new_idx -= tmp_inc_size;
inc_size += tmp_inc_size;
res += new_val;
} else {
res += tmp[new_idx];
}
if (stk.empty())
break;
++new_idx;
}
return { tmp.substr(0, new_idx+1), new_idx + inc_size};
}
int calculate(string s) {
int res = 0;
char op = '+';
int tmp = 0;
bool has_num = false;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '(') {
const auto [str, index] = Parse(s.substr(i));
tmp += calculate(str);
i += index;
has_num = true;
} else if (s[i] >= '0' && s[i] <= '9') {
tmp = tmp*10 - '0' + s[i];
has_num = true;
} else if (s[i] == ' '){
continue;
} else {
const bool is_con = !has_num?true:false;
res += op == '-'? -1 * tmp : tmp;
tmp = 0;
op = is_con? (s[i] == op?'+':'-') : s[i] == '-'?'-':'+';
has_num = false;
}
}
res += op == '-'? -1 * tmp : tmp;
return res;
}
// 227. Basic Calculator II
int calculate(string s) {
int s_len = s.size();
int cur_res = 0;
int fin_res = 0;
char ope = '+';
int cur_num = 0;
for (int idx = 0; idx < s_len; ++idx) {
if (isdigit(s[idx])) {
cur_num = cur_num*10 + (s[idx] - '0');
}
if (s[idx] == '*' || s[idx] == '/' || s[idx] == '+'
|| s[idx] == '-' || idx == s_len - 1) {
switch(ope) {
case '+': cur_res += cur_num; break;
case '-': cur_res -= cur_num; break;
case '*': cur_res *= cur_num; break;
case '/': cur_res /= cur_num; break;
}
if (s[idx] == '-' || s[idx] == '+' || s_len - 1 == idx) {
fin_res += cur_res;
cur_res = 0;
}
cur_num = 0;
ope = s[idx];
}
}
return fin_res;
}
// 772. Basic Calculator III
string parserString (string s, int idx, int & new_idx) {
int num_brance = 1;
string str = "";
for (int i = idx; i < s.size(); ++i) {
if (s[i] == '(') {
++num_brance;
}
else if (s[i] == ')') {
--num_brance;
}
if (!num_brance) {
new_idx = i;
return str;
}
str += s[i];
}
return str;
}
int calculate(string s) {
int s_len = s.size();
long long cur_num = 0;
int cur_res = 0;
int fin_res = 0;
char ope = '+';
for (int idx = 0; idx < s_len; ++idx) {
if (s[idx] == '(') {
int new_idx = 0;
string str = parserString(s, idx+1, new_idx);
cur_num = calculate(str);
idx = new_idx;
}
if (isdigit(s[idx])) {
cur_num = cur_num*10 + (s[idx] - '0');
}
if (s[idx] == '+' || s[idx] == '-' || s[idx] == '*' ||
s[idx] == '/' || s_len == idx + 1) {
switch(ope) {
case '+': cur_res += cur_num; break;
case '-': cur_res -= cur_num; break;
case '*': cur_res *= cur_num; break;
case '/': cur_res /= cur_num; break;
}
if (s[idx] == '-' || s[idx] == '+' || s_len - 1 == idx) {
fin_res += cur_res;
cur_res = 0;
}
ope = s[idx];
cur_num = 0;
}
}
return fin_res;
}
// 51. N-Queens
static constexpr int kNum = 10;
char kQueen[kNum][kNum];
bool row[kNum] = {false};
bool col[kNum] = {false};
bool dg[2*kNum] = {false};
bool udg[2*kNum] = {false};
void StoreResult(const int N, vector<vector<string>>& ans) {
vector<string> sol;
for (int i = 0; i < N; ++i) {
string tmp;
for (int j = 0; j < N; ++j) {
tmp += kQueen[i][j];
}
sol.push_back(tmp);
}
ans.push_back(sol);
}
void DFS(int x, int y,
const int n, const int N,
vector<vector<string>>& ans) {
if (n > N) return;
if (y == N) {
y = 0;
++x;
}
if (x == N) {
if (n == N) {
StoreResult(N, ans);
}
return;
}
kQueen[x][y] = '.';
DFS(x, y+1, n, N, ans);
if (!row[y] && !col[x] && !dg[x+y] && !udg[-y+x+N]) {
row[y] = col[x] = dg[x+y] = udg[-y+x+N] = true;
kQueen[x][y] = 'Q';
DFS(x, y + 1, n+1, N, ans);
row[y] = col[x] = dg[x+y] = udg[-y+x+N] = false;
kQueen[x][y] = '.';
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ans;
DFS(0, 0, 0, n, ans);
return ans;
}
// Geometry part
