随机刷题
且矿石数量相差不超过1个
条件!#include
#include
#include
#include
#include
#include // INT_MIN
using namespace std;
#define MAX_NUM 101
int solution(int n, int weight[]) {
int sum = 0, h_sum, h_n = (n + 1) / 2;
for (int i = 0; i < n; i++) sum += weight[i];
h_sum = sum / 2;
vector<vector<int>> dp(h_sum + 1, vector<int>(h_n + 1, INT_MIN));
for (int i = 0; i <= h_sum; i++) dp[i][0] = 0;
for (int i = 0; i < n; i++) {
auto tmp = dp; // 避免覆盖!
for (int j = weight[i]; j <= h_sum; j++) {
for (int k = 1; k <= h_n; k++)
tmp[j][k] = max(tmp[j][k], dp[j-weight[i]][k-1]+weight[i]);
}
dp = tmp;
}
if (n % 2) return sum - 2 * max(dp[h_sum][h_n], dp[h_sum][h_n-1]);
else return sum - 2 * dp[h_sum][h_n];
}
int main()
{
string str("");
getline(cin, str);
int a[MAX_NUM];
int i = 0;
char *p;
int count = 0;
const char* strs = str.c_str();
p = strtok((char *)strs, " ");
while(p) {
a[i] = atoi(p);
count++;
p = strtok(NULL, " ");
i++;
if(i >= MAX_NUM)
break;
}
int result = solution(count, a);
cout << result << endl;
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
typedef struct _node
{
int num;
struct _node * next;
}node;
void solution(int N, int M)
{
if (N < 1 || M < 1) return;
vector<int> rows(N, 0);
for (int i = 0; i < N; i++) rows[i] = i + 1;
int pos = 0;
while (rows.size() > 0) {
pos += M - 1;
pos %= rows.size();
cout << rows[pos] << " ";
rows.erase(rows.begin() + pos);
}
cout << endl;
}
int main()
{
int N;
int M;
string str("");
getline(cin, str);
char *p;
const char* strs = str.c_str();
p = strtok((char *)strs, " ");
N = atoi(p);
p = strtok(NULL, " ");
M = atoi(p);
solution(N, M);
return 0;
}
#include
#include
#include
using namespace std;
int solution(int a[], int N)
{
int pre = 0, cur = 0;
int steps = 0;
for (int i = 0; i < N - 1; i++) {
cur = max(cur, i+a[i]);
if (pre == i) {
pre = cur;
steps++;
if (cur >= N - 1)
break;
}
}
return pre >= N - 1 ? steps : -1;
}
int main()
{
string str("");
getline(cin, str);
int a[2000];
int i = 0;
char *p;
int count = 0;
const char* strs = str.c_str();
p = strtok((char *)strs, " ");
while(p)
{
a[i] = atoi(p);
count++;
p = strtok(NULL, " ");
i++;
if(i >= 2000)
break;
}
int num = solution(a, count);
cout << num << endl;
return 0;
}
//write code here
vector<vector<vector<int>>> dp(countOfApp + 1,vector<vector<int>>(disk+1,vector<int>(mem+1)));
for(int i = 1; i <= countOfApp; i++){
for(int j = disk; j > 0; j--){
for(int k = mem; k > 0; k--){
if(j >= disks[i-1] && k >= mems[i-1]){
dp[i][j][k] = max(dp[i - 1][j][k],dp[i - 1][j - disks[i-1]][k - mems[i-1]]+ users[i-1]);
}else{
dp[i][j][k] = dp[i - 1][j][k];
}
}
}
}
return dp[countOfApp][disk][mem];
int dfs(int boxs[], int N, int start, int end, int k, vector<vector<vector<int>>>& dp) {
if (start > end) return 0;
if (dp[start][end][k] > 0) return dp[start][end][k];
for (int i = start; i < end; i++) {
if (boxs[start] != boxs[i + 1]) break;
k++; start++;
}
int res = dfs(boxs, N, start + 1, end, 0, dp) + (k + 1) * (k + 1);
for (int i = start + 1; i <= end; i++) {
if (boxs[i] != boxs[start]) continue;
res = max(res, dfs(boxs, N, start + 1, i - 1, 0, dp) + dfs(boxs, N, i, end, k + 1, dp));
}
return dp[start][end][k] = res;
}
int solution(string str)
{
int left = 0, right = 0;
for (int i = 0; i < str.size(); i++) {
if (str[i] == '0') break;
if (str[i] == '(') left++;
if (str[i] == ')') left--;
}
for (int i = str.size() - 1; i>= 0; i--) {
if (str[i] == '0') break;
if (str[i] == ')') right++;
if (str[i] == '(') right--;
}
return min(left, right);
}
#include
#include
vector<int> inputArray1() {
string inputs;
cin >> inputs;
// splits
vector<string> splits;
int start = 0;
for (size_t i = 0; i < inputs.size(); i++) {
if (inputs[i] == ',') {
splits.push_back(inputs.substr(start, i - start));
start = i + 1;
}
}
if (start != (int)inputs.size()) {
splits.push_back(inputs.substr(start));
}
vector<int> res;
for (string s : splits) {
res.push_back(std::stoi(s));
// cout << res.back() << " ";
}
return res;
}
vector<int> inputArray2() {
vector<int> inputs;
int a;
do {
cin >> a;
inputs.push_back(a);
// cout << a << " ";
} while (getchar() != '\n');
return inputs;
}
vector<int> inputArray3() {
int size = 0;
cin >> size;
vector<int> inputs;
for (int i = 0; i < size; i++) {
int tmp;
cin >> tmp;
cout << tmp << " ";
inputs.push_back(tmp);
}
return inputs;
}
vector<vector<int>> inputMatrix() {
int m, n;
cin >> m >> n;
vector<vector<int>> matrix(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int a;
cin >> a;
matrix[i][j] = a;
}
}
return matrix;
}
输入: 123
输出: 321
class Solution {
public:
int reverse(int x) {
int res = 0;
while (x != 0) {
if (abs(res)>INT_MAX/10) return 0;
res = res*10+(x%10);
x/=10;
}
return res;
}
};
后序遍历的下一个元素,不知道对不对!
// 这是后序遍历时的下一个节点
// Pa(X).right.最左 - 同层右节点的最左节点
if (!pNode) return NULL;
if (!pNode->next) return NULL;
TreeLinkNode *root = pNode->next;
if (!root->right || root->right == pNode)
return root;
root = root->right;
while (root->left)
root = root->left;
return root;
以此为启发!
先序遍历的下一个节点:
中序遍历的下一个节点:
后序遍历的下一个节点:
class Solution {
private:
bool loopJudge(vector<int>& seq) {
int left = 0, right = seq.size() - 1;
while (left < seq.size() && right >= 0 && left < right) {
if (seq[left++] != seq[right--]) return false;
}
return true;
}
public:
bool isSymmetrical(TreeNode* pRoot) {
if (!pRoot) return true;
queue<TreeNode*> que;
que.push(pRoot);
while (!que.empty()) {
int sz = que.size();
vector<int> seq;
for (int i = 0; i < sz; i++) {
auto x = que.front(); que.pop();
if (!x) seq.push_back(INT_MIN);
else seq.push_back(x->val);
if (x) {
que.push(x->left);
que.push(x->right);
}
}
if (!loopJudge(seq)) return false;
}
return true;
}
};
或者用两个que,一个保存左子树的左右子节点,一个保存右子树的右左子节点,注意顺序!刷题日记(1)里面就是!
而如何写递归?
1 观察是否有递归结构
2 处理递归子结构(如该题就是一个高度为3的二叉树的处理结果!)
class Solution {
public:
bool isSymmetrical(TreeNode* pRoot) {
if (!pRoot) return true;
return dfs(pRoot->left, pRoot->right);
}
bool dfs(TreeNode* left, TreeNode* right) {
if (!left) return !right;
if (!right) return !left;
return (left->val == right->val) &&
dfs(left->left,right->right) &&
dfs(left->right,right->left);
}
};
1 用双栈,一个先left再right堆入,一个先right再left堆入,两个栈交叠进行
2 用双端队列,分奇偶左右导出!
剑指offer
OJ链接
题解 链接
class Solution {
public:
int lastRemaining(int n, int m) {
if (n == 1) return 0;
return (lastRemaining(n-1,m) + m) % n;
}
};
使用有限状态机做 … if-else之流的太蛋疼了
先设定开始状态(未处理时)为0
再确定有几种状态:
1 | 点状态 | 类似于" . " |
2 | 正负号 | 类似于" + " |
3 | 整数 | 类似于"132" |
4 | 浮点数 | 类似于"3.2" |
5 | 科学计数 | 类似于"5e3" |
6 | 数加e状态 | 类似于"5e" |
7 | 数加e加正负状态 | 类似于"5e+" |
8 | 额外状态 | 以便处理尾空格情况 |
class Solution {
public:
bool isNumber(string s) {
// 状态x操作
// 状态:0起始状态 1点 2正负 3整数 4浮点数 5科学计数 6数+"e" 7数+”正负"+"e"
// 中间状态1/2/6/7
// 完美状态3/4/5
// 操作:0数 1空 2点 3正负 4e
// 添一个空状态8 以处理尾部空格
s += ' '; // 添上一个尾部空格
vector<vector<int>> State {
{3, 0, 1, 2,-1},
{4,-1,-1,-1,-1},
{3,-1, 1,-1,-1},
{3, 8, 4,-1, 6},
{4, 8,-1,-1, 6},
{5, 8,-1,-1,-1},
{5,-1,-1, 7,-1},
{5,-1,-1,-1,-1},
{-1,8,-1,-1,-1}
};
vector<int> legalState {3,4,5,8};
int sta = 0;
for (auto& c : s) {
if (c >= '0' && c <= '9') sta = State[sta][0];
else if (c == ' ') sta = State[sta][1];
else if (c == '.') sta = State[sta][2];
else if (c == '+' || c == '-') sta = State[sta][3];
else if (c == 'e') sta = State[sta][4];
else sta = -1;
if (sta == -1) return false;
}
for (auto& ls : legalState)
if (sta == ls) return true;
return false;
}
};
class Solution {
private:
int minL;
public:
vector<vector<string>> findLadders(string beginWord, string endWord,
vector<string>& wordList) {
if (find(wordList.begin(), wordList.end(), endWord) == wordList.end()) return {};
minL = INT_MAX;
vector<vector<string>> res;
vector<string> tmp;
tmp.push_back(beginWord);
backstrck(beginWord, endWord, wordList, res, tmp);
return res;
}
void backstrck(string& be, string& en, vector<string>& dict, vector<vector<string>>& res, vector<string>& tmp) {
if (be == en) {
if (minL > tmp.size()) {
res.clear();
minL = tmp.size();
res.push_back(tmp);
} else if (minL == tmp.size()) {
res.push_back(tmp);
}
return;
}
if (tmp.size() >= minL) return;
for (int i = 0; i < dict.size(); i++) {
auto x = dict[i];
if (find(tmp.begin(), tmp.end(), x) != tmp.end() || !oneChanged(be, x)) continue;
tmp.push_back(x);
backstrck(x,en,dict,res,tmp);
tmp.pop_back();
}
}
bool oneChanged(string& beginWord, string& curWord) {
int count = 0;
for (int i = 0; i < beginWord.length(); i++) {
if (beginWord[i] != curWord[i]) count++;
if (count == 2) return false;
}
return count == 1;
}
};
class Solution {
public:
//判断两个单词能否互相转换
bool check_transform(string &word1, string &word2){
int difference = 0;
for(int i = 0; i < word1.length() && difference < 2; i++){
if(word1[i] != word2[i])
difference++;
}
return difference == 1;
}
vector<vector<string>> findLadders(string beginWord, string endWord,
vector<string>& wordList) {
unordered_map<string, int> wordId; //word->ID的映射
vector<string> idWord; //ID->word的映射
vector<vector<int>> edges; //构造图
int id = 0;
for(int i = 0; i < wordList.size(); i++){
if(!wordId.count(wordList[i])){
wordId[wordList[i]] = id++;
idWord.push_back(wordList[i]);
}
}
if(!wordId.count(endWord))
return {}; //不存在结束单词,返回空
if(!wordId.count(beginWord)){
wordId[beginWord] = id++; //加入起始单词
idWord.push_back(beginWord);
}
//构造图
edges.resize(id);
for(int i = 0; i < idWord.size(); i++){
for(int j = i + 1; j < idWord.size(); j++){
if(check_transform(idWord[i], idWord[j])){
edges[i].push_back(j);
edges[j].push_back(i); //构造两条有向边
}
}
}
int endWord_id = wordId[endWord];
vector<vector<string>> res;
queue<vector<int>> q;
q.push(vector<int>{wordId[beginWord]}); //起始单词作为一个路径入队
//cost[id]:从起始单词出发,转换到id所代表的单词所需的次数(代价)
vector<int> cost(id, INT_MAX);
cost[wordId[beginWord]] = 0;
while(!q.empty()){
vector<int> now_path = q.front();
q.pop();
int last_word_id = now_path.back();
//当前路径最后一个为结束单词时
if(last_word_id == endWord_id){
vector<string> temp;
for(int i = 0; i < now_path.size(); i++){
temp.push_back(idWord[now_path[i]]);
}
res.push_back(temp);
} else {
for(int i = 0; i < edges[last_word_id].size(); i++){
//路径最后一个单词的连接单词
int next = edges[last_word_id][i];
if(cost[last_word_id] + 1 <= cost[next]){
cost[next] = cost[last_word_id] + 1; //更新转换次数
vector<int> temp(now_path.begin(), now_path.end());
temp.push_back(next);
q.push(temp);
}
}
}
}
return res;
}
};
#include
#include
using namespace std;
int main() {
long long n, k; // n次击鼓传花 k个人
cin >> n >> k;
vector<vector<long long>> dp(n + 1, vector<long long>(k));
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < k; j++) {
dp[i][j] = (dp[i - 1][(j - 1 + k) % k] +
dp[i - 1][(j + 1) % k]) % 1000000007;
}
}
cout << dp[n][0] << endl;
return 0;
}
#include
#include
#include
using namespace std;
int dx[4] = { 0, 1, 0, -1 };
int dy[4] = { 1, 0, -1, 0 };
int dfs_dp(int y, int x, int k, vector<vector<int>>& mat, vector<vector<vector<int>>>& dp) {
int N = dp.size(), M = dp[0].size(), K = dp[0][0].size();
if (dp[y][x][k] != -1) return dp[y][x][k];
dp[y][x][k] = 1;
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M)
continue;
if (mat[y][x] < mat[ny][nx])
dp[y][x][k] = max(dp[y][x][k], dfs_dp(ny, nx, k, mat, dp) + 1);
if (mat[y][x] >= mat[ny][nx] && k > 0)
dp[y][x][k] = max(dp[y][x][k], dfs_dp(ny, nx, k - 1, mat, dp) + 1);
}
return dp[y][x][k];
}
int main() {
int n, m, k;
cin >> n >> m >> k;
// 迷宫
vector<vector<int>> mat(n, vector<int>(m));
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> mat[i][j];
// 迷宫中(n,m)按k次走的最多步
vector<vector<vector<int>>> dp(n,vector<vector<int>>(m,
vector<int>(k+1, -1)));
int max_res = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
max_res = max(max_res,
dfs_dp(i, j, k, mat, dp));
cout << max_res << endl;
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
string reverse(string str1) {
int left = 0, right = str1.size() - 1;
while (left < right)
swap(str1[left++], str1[right--]);
return str1;
}
string dfs(string& s, int& pos) {
string res = "";
while (pos >= 0 && s[pos] != '(') {
// 反转后: '()' -> ')('
if (s[pos] < '0' || s[pos] > '9') // 字母
res.push_back(s[pos--]);
else {
int times = 1, num = 0;
while (s[pos] >= '0' && s[pos] <= '9') {
num += (s[pos--] - '0') * times;
times *= 10;
}
string t;
if (s[pos] == ')') { // "3)ABC("
pos--; // 跳过 [
t = dfs(s, pos);
pos--; // 跳过 ]
} else t = s[pos--]; // "3ABC"
for (int i = 0; i < num; i++) res += t;
}
}
return res;
}
int main() {
int len = -1;
cin >> len;
for (int i = 0; i < len; i++) {
string in_str;
cin >> in_str;
int pos = in_str.size() - 1;
cout << reverse(dfs(in_str, pos)) << endl;
}
return 0;
}
#include
#include
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> arr(n, vector<int>(m));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int t;
cin >> t;
arr[i][j] = t;
}
}
// Handle
vector<vector<int>> dirs{ { 1,0 },{ 0,1 },{ -1,0 },{ 0, -1 } };
int dir = 0;
int y = -1, x = 0;
m--;
while (m >= 0 && n >= 0) {
int looptime = (dir % 2) ? m-- : n--;
for (int i = 0; i < looptime; i++) {
y += dirs[dir][0];
x += dirs[dir][1];
cout << arr[y][x] << " ";
}
dir = (dir + 1) % 4;
}
return 0;
}
#include
#include
#include
using namespace std;
int main() {
int n, s;
cin >> n >> s;
vector<int> v;
for (int i = 0; i < n; i++) {
int t;
cin >> t;
v.push_back(t);
}
// Handle
int left = 0, right = 0;
int sum = 0, mlen = 0;
while (right < n) {
sum += v[right];
right++;
while (sum > s) {
sum -= v[left];
left++;
}
mlen = max(mlen, right - left);
}
cout << mlen << endl;
return 0;
}
猿辅导高频算法题整理 - 牛客网
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* dummy1 = new ListNode(-1);
ListNode* dummy2 = new ListNode(-1);
ListNode *p1 = dummy1, *p2 = dummy2;
while (head) {
if (head->val < x) {
p1->next = head;
p1 = p1->next;
} else {
p2->next = head;
p2 = p2->next;
}
head = head->next;
}
p2->next = NULL;
p1->next = dummy2->next;
return dummy1->next;
}
};
递归DFS
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int len(ListNode* pNode) {
int length = 0;
while (pNode) {
pNode = pNode->next;
length++;
}
return length;
}
void dfs(ListNode* l1, ListNode* l2, ListNode* pre, int len1, int len2) {
if (!l1) return;
if (len1 > len2) {
dfs(l1->next, l2, l1, len1-1, len2);
} else {
dfs(l1->next, l2->next, l1, len1-1, len2-1);
l1->val += l2->val;
}
int p = l1->val / 10;
pre->val += p;
l1->val %= 10;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int len1 = len(l1), len2 = len(l2);
ListNode* node = new ListNode(0);
if (len1 > len2) {
dfs(l1, l2, node, len1, len2);
node->next = l1;
} else {
dfs(l2, l1, node, len2, len1);
node->next = l2;
}
return node->val ? node : node->next;
}
};
栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
stack<int> s1, s2;
while (l1) {
s1.push(l1->val);
l1 = l1->next;
}
while (l2) {
s2.push(l2->val);
l2 = l2->next;
}
ListNode* out = new ListNode(0);
while (!s1.empty() || !s2.empty()) {
int num = 0;
if(!s1.empty()) {
num += s1.top();
s1.pop();
}
if (!s2.empty()) {
num += s2.top();
s2.pop();
}
int sum_num = (out->val + num);
out->val = sum_num % 10;
ListNode* tmp = new ListNode(sum_num / 10);
tmp->next = out;
out = tmp;
}
return out->val ? out : out->next;
}
};
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
if (!root) return 0;
int dia = 0;
dfs(root, dia);
return dia;
}
int dfs(TreeNode* root, int& dia) {
if (!root) return 0;
int L = dfs(root->left, dia);
int R = dfs(root->right, dia);
dia = max(dia, L + R);
return max(L, R) + 1;
}
};
递归
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head || !head->next) return head;
head->next = deleteDuplicates(head->next);
if (head->val == head->next->val) head = head->next;
return head;
}
};
迭代
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head) return head;
ListNode *out = head;
while (head && head->next) {
if (head->val == head->next->val)
head->next = head->next->next;
else head = head->next;
}
return out;
}
};
class SortedStack {
private:
stack<int> s1, s2; // 前者三角形 后者倒三角 二合一是排好序的
public:
SortedStack() {}
void push(int val) {
while (!s1.empty() && s1.top() < val) {
s2.push(s1.top());
s1.pop();
}
while (!s2.empty() && s2.top() > val) {
s1.push(s2.top());
s2.pop();
}
s1.push(val);
}
void pop() {
while (!s2.empty()) {
s1.push(s2.top());
s2.pop();
}
if (!s1.empty())
s1.pop();
}
int peek() {
while (!s2.empty()) {
s1.push(s2.top());
s2.pop();
}
if (!s1.empty()) return s1.top();
else return -1;
}
bool isEmpty() {
return s1.empty() && s2.empty();
}
};
class Solution {
public:
int closedIsland(vector<vector<int>>& grid) {
int cnt = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == 0 && dfs(grid, i, j))
cnt++;
}
}
return cnt;
}
bool dfs(vector<vector<int>>& grid, int y, int x) {
if (y < 0 || y >= grid.size() || x < 0 || x >= grid[0].size())
return false;
if (grid[y][x] == 0) grid[y][x] = -1;
else return true;
bool up = dfs(grid, y - 1, x);
bool dw = dfs(grid, y + 1, x);
bool lt = dfs(grid, y, x - 1);
bool rt = dfs(grid, y, x + 1);
return up && dw && lt && rt;
}
};
class Solution {
private:
ListNode* out = NULL;
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
dfs(head, k);
return out;
}
void dfs(ListNode* head, int& k) {
if (!head) return;
dfs(head->next, k);
if (--k== 0 && !out) out = head;
}
};
DFS
:状态转移图:状态2^N,操作N个
class Solution {
private:
struct State {
int cover;
int i;
State(int _cover, int _i) : cover(_cover), i(_i) {}
};
public:
int shortestPathLength(vector<vector<int>>& adj) {
const int N = adj.size();
const int END = (1 << N) - 1;
vector<State> currs;
vector<vector<int>> dist(1 << N, vector<int>(N, 0)); // 标记是否已遍历
// 从所有点(同时)出发BFS
for (int i = 0; i < N; ++i) {
currs.push_back(State(1 << i, i));
dist[1 << i][i] = 0;
}
// 层次遍历
for (int level = 0; !currs.empty(); ++level) {
vector<State> nexts;
for (auto curr : currs) {
for (int j : adj[curr.i]) {
int v = curr.cover | (1 << j);
if (v == END) return level + 1; // 终点
if (!dist[v][j]) {
dist[v][j] = 1;
nexts.push_back(State(v, j));
}
}
}
currs = nexts;
}
return 0;
}
};
DP
:cover 表示一条路径上访问过的节点集合,head 表示当前节点。dist[cover][head] 存储路径 (cover, head) 的长度。
class Solution {
public:
int shortestPathLength(vector<vector<int>>& graph) {
int N = graph.size();
int target = (1 << N) - 1;
vector<vector<int>> dp(target+1, vector<int>(N, N * N));
for (int i = 0; i < N; i++) dp[1 << i][i] = 0;
for (int i = 0; i <= target; i++) {
bool repeat = true;
while (repeat) {
repeat = false;
for (int j = 0; j < N; j++) {
int dist = dp[i][j];
for (auto next : graph[j]) {
int x = i | (1 << next);
if (dist + 1 < dp[x][next]) {
dp[x][next] = dist + 1;
if (x == i) repeat = true;
}
}
}
}
}
int out = N * N;
for (auto x : dp[target])
out = min(out, x);
return out;
}
};
BFS
广搜
class Solution {
private:
struct State {
int y, x;
int e;
State(int _y, int _x, int _e) : x(_x), y(_y), e(_e) {}
};
int delta_yx[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
public:
int shortestPath(vector<vector<int>>& grid, int k) {
int N = grid.size(), M = grid[0].size();
if (N == 1 && M == 1) return 0;
k = min(k, N + M - 2);
bool visited[N][M][k+1];
memset(visited, false, sizeof(visited));
queue<State> q;
q.emplace(0, 0, k);
visited[0][0][k] = true;
int steps = 0;
while (!q.empty()) {
int len = q.size();
steps++;
for (int i = 0; i < len; i++) {
auto cur_s = q.front(); q.pop();
for (int j = 0; j < 4; j++) {
int yd = cur_s.y + delta_yx[j][0];
int xd = cur_s.x + delta_yx[j][1];
if (yd < 0 || xd < 0 || yd >= N || xd >= M)
continue;
if (grid[yd][xd] == 0 &&
!visited[yd][xd][cur_s.e]) {
if (yd == N - 1 && xd == M - 1)
return steps;
visited[yd][xd][cur_s.e] = true;
q.emplace(yd, xd, cur_s.e);
}
else if (grid[yd][xd] == 1 && cur_s.e > 0 &&
!visited[yd][xd][cur_s.e-1]) {
visited[yd][xd][cur_s.e-1] = true;
q.emplace(yd, xd, cur_s.e - 1);
}
}
}
}
return -1;
};
};
DFS
深度优先搜索
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseL(ListNode* left, ListNode* right) {
if (left == right) return left;
ListNode* pre = NULL, *cur = left;
while (cur != right) {
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if (!head) return NULL;
ListNode *x = head, *y = head;
for (int i = 0; i < k; i++) {
if (!y) return head;
y = y->next;
}
ListNode* last = reverseL(x, y);
x->next = reverseKGroup(y, k);
return last;
}
};
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int len = nums.size();
if (len < 2) return;
k = k % len;
int left = 0, right = len - k - 1;
while (left < right)
swap(nums[left++], nums[right--]);
left = len - k, right = len - 1;
while (left < right)
swap(nums[left++], nums[right--]);
left = 0, right = len - 1;
while (left < right)
swap(nums[left++], nums[right--]);
}
};
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if (!root) return root;
TreeNode* left = mirrorTree(root->left);
TreeNode* right = mirrorTree(root->right);
root->left = right;
root->right = left;
return root;
}
};
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
if (!root) return {};
vector<vector<int>> out;
vector<int> tmp; tmp.push_back(root->val);
backtrack(root, tmp, out, root->val, sum);
return out;
}
void backtrack(TreeNode* node, vector<int>& tmp,
vector<vector<int>>& out, int sum, int S) {
if (node && !node->right && !node->left) { // leaf node
if (sum == S)
out.push_back(tmp);
}
if (node->left) {
tmp.push_back(node->left->val);
backtrack(node->left, tmp, out, sum + node->left->val, S);
tmp.pop_back();
}
if (node->right) {
tmp.push_back(node->right->val);
backtrack(node->right, tmp, out, sum + node->right->val, S);
tmp.pop_back();
}
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> m;
for (int i = 0; i < nums.size(); i++) {
int rest = target - nums[i];
if (m.count(rest) != 0) return {m[rest], i};
m[nums[i]] = i;
}
return {-1, -1};
}
};
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if (matrix.empty()) return false;
int N = matrix.size(), M = matrix[0].size();
int y = N - 1, x = 0;
while (y >= 0 && y < N && x >= 0 && x < M) {
if (matrix[y][x] == target) return true;
else if (matrix[y][x] > target) y--;
else if (matrix[y][x] < target) x++;
}
return false;
}
};
class Solution {
public:
bool balanced = true;
bool isBalanced(TreeNode* root) {
het_count(root);
return balanced;
}
int het_count(TreeNode* node) {
if (!node) return 0;
if (!balanced) return -1; //剪枝
int lt = het_count(node->left);
int rt = het_count(node->right);
if (abs(lt - rt) > 1)
balanced = false;
return max(lt, rt) + 1;
}
};
长这个样子
1
/ \
2 3
/ \ /
4 5 6
class Solution {
public:
int countNodes(TreeNode* root) {
int left = 0, right = 0;
TreeNode* node = root;
while (node) {
left++;
node = node->left;
}
node = root;
while (node) {
right++;
node = node->right;
}
if (left == right) return pow(2, left) - 1;
else return 1 + countNodes(root->left) +
countNodes(root->right);
}
};
class Solution {
private:
Node *pre = NULL, *head = NULL;
public:
void dfs(Node* root) {
if (!root) return;
dfs(root->left);
if (!head) {
head = root;
pre = root;
} else {
pre->right = root;
root->left = pre;
pre = root;
}
dfs(root->right);
}
Node* treeToDoublyList(Node* root) {
if (!root) return root;
dfs(root);
head->left = pre; // cycle
pre->right = head;
return head;
}
};
class Solution {
private:
bool isBST = true;
TreeNode* pre = NULL;
public:
bool isValidBST(TreeNode* root) {
if (!root || !isBST)
return isBST;
isValidBST(root->left);
if (!pre) pre = root;
else {
if (root->val <= pre->val)
isBST = false;
else pre = root;
}
isValidBST(root->right);
return isBST;
}
};
快排思想
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
if (n < k) return -1;
int left = 0, right = nums.size() - 1;
while (true) {
int pos = partition(nums, left, right);
if (pos == k) return nums[k - 1];
else if (pos > k) right = pos - 1;
else left = pos;
}
return nums[k - 1];
}
int partition(vector<int>& nums, int left, int right) {
if (left > right) return -1;
if (left == right) return left + 1;
int pivot = nums[left];
int c1 = left, c2 = right;
while (c1 < c2) {
while (c1 < c2 && nums[c2] <= pivot) c2--;
if (c1 < c2) nums[c1++] = nums[c2];
while (c1 < c2 && nums[c1] > pivot) c1++;
if (c1 < c2) nums[c2--] = nums[c1];
}
nums[c1] = pivot;
return c1 + 1;
}
};
推排思想
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
for (int i = n / 2 - 1; i >= 0; i--) {
heapBuild(nums, i, n);
}
for (int i = n - 1; i >= n - k + 1; i--) {
swap(nums[0], nums[i]);
heapBuild(nums, 0, i);
}
return nums[0];
}
void heapBuild(vector<int>& nums, int root, int end) {
int left = 2 * root + 1;
if (left >= end) return;
int right = left + 1;
int maxIdx = ((right < end) && (nums[right] > nums[left]))?right:left;
if (nums[maxIdx] < nums[root]) return;
swap(nums[maxIdx], nums[root]);
heapBuild(nums, maxIdx, end);
}
};
class Solution {
public:
int reverse(int x) {
string str = to_string(x);
bool sgn = (str[0] != '-');
if (!sgn) str.erase(str.begin());
int left = 0, right = str.size() - 1;
while (left < right)
swap(str[left++], str[right--]);
long out = stol(str);
if (!sgn) out = -1 * out;
if (out < INT_MIN || out > INT_MAX)
return 0;
return out;
}
};
class Solution {
public:
int reverse(int x) {
string str = to_string(x);
bool sgn = (str[0] != '-');
if (!sgn) str.erase(str.begin());
int left = 0, right = str.size() - 1;
while (left < right)
swap(str[left++], str[right--]);
long out = stol(str);
if (!sgn) out = -1 * out;
if (out < INT_MIN || out > INT_MAX)
return 0;
return out;
}
};
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
levelInsertDFS(root, 0, res);
return res;
}
void levelInsertDFS(TreeNode* node, int level, vector<vector<int>>& res) {
if (!node) return;
if (res.size() == level) res.push_back({});
res[level].push_back(node->val);
if (node->left) levelInsertDFS(node->left,level+1,res);
if (node->right) levelInsertDFS(node->right,level+1,res);
}
};
BFS写法
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if (!root) return {};
vector<vector<int>> out;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int sz = q.size();
vector<int> tmp;
for (int i = 0; i < sz; i++) {
auto x = q.front(); q.pop();
tmp.push_back(x->val);
if (x->left) q.push(x->left);
if (x->right) q.push(x->right);
}
out.push_back(tmp);
}
return out;
}
};
暴力
class Solution {
public:
int record(vector<vector<int>>& M, int y, int x, int dy, int dx) {
int H = M.size(), W = M[0].size();
int out = 0, maxV = 0;
while (!(y < 0 || y >= H || x < 0 || x >= W)) {
if (M[y][x]) maxV = max(maxV, ++out);
else out = 0;
y += dy;
x += dx;
}
return maxV;
}
int longestLine(vector<vector<int>>& M) {
if (M.empty()) return 0;
int H = M.size(), W = M[0].size();
int out = INT_MIN;
for (int i = 0; i < H; i++) {
out = max(out, record(M, i, 0, 0, 1));
out = max(out, record(M, i, 0, 1, 1));
out = max(out, record(M, i, W - 1, 1, -1));
}
for (int i = 0; i < W; i++) {
out = max(out, record(M, 0, i, 1, 0));
out = max(out, record(M, 0, i, 1, 1));
out = max(out, record(M, 0, i, 1, -1));
}
return out;
}
};
1维DP
2维DP
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int N = nums.size();
if (N == 0) return 1;
for (int i = 0; i < N; i++) {
while (nums[i] > 0 && nums[i] < N && nums[i] != nums[nums[i] - 1])
swap(nums[i], nums[nums[i] - 1]);
}
for (int i = 0; i < N; i++)
if (nums[i]!= i + 1) return i + 1;
return N + 1;
}
};
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int n = nums.size();
vector<int> out;
for (int i = 0; i < n; i++) {
int pos = abs(nums[i]) - 1;
if (nums[pos] >= 0) nums[pos] *= -1;
}
for (int i = 0; i < n; i++)
if (nums[i] > 0)
out.push_back(i + 1);
return out;
}
};
递归
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head) return head;
if (head->next && head->next->val == head->val) {
while (head->next && head->next->val == head->val)
head = head->next;
return deleteDuplicates(head->next);
} else head->next = deleteDuplicates(head->next);
return head;
}
};
迭代
快慢指针
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head || !head->next) return head;
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *slow = dummy, *fast = head;
while (fast) {
while (fast->next && fast->val == fast->next->val)
fast = fast->next;
if (slow->next == fast) slow = slow->next;
else slow->next = fast->next;
fast = fast->next;
}
return dummy->next;
}
};
递归
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res = {};
if (!root) return res;
inorder(root, res);
return res;
}
void inorder(TreeNode* root, vector<int>& res) {
if (!root) return;
if (root->left) inorder(root->left, res);
res.push_back(root->val);
if (root->right) inorder(root->right, res);
}
};
栈
TODO