#include
#include
#include
using namespace std;
class Solution{
public:
vector maxInWindows(vector& nums, int k) // k是窗口的大小
{
vector res;
deque q;
for(int i = 0; i < nums.size(); i++)
{
while(q.size() && q.front() <= i - k) q.pop_front(); // 将已经划出窗口中的元素从队列中删除
while(q.size() && nums[q.back()] <= nums[i]) nums.pop_back(); // 如果在队尾插入的元素大于等于当前队尾的元素值,就可以删除队尾的元素!
q.push_back(i);
if(i >= k - 1) res.push_back(nums[q.front()]);
}
return res;
}
};
#include
#include
using namespace std;
// dfs方法来解决:注意两点,第一是状态的表示是什么(从输出中来)?第二是按照什么顺序来计算第一步中的状态?
class Solution{
public:
vector numberOfDice(int n){
vector res;
for(int i = n; i <= 6 * n; i++) res.push_back(dfs(n, i)); // dfs(n, s)表示的就是所要输出的结果;也就是每次求总和是s的情况下,一共投了n次骰子,一共有多少种方案
return res;
}
int dfs(int n, int sum){
if(sum < 0) return 0;
if(n == 0) return !sum;
for(int i = 1; i <= 6; i++)
{
res += dfs(n - 1, sum - i); // 热狗法:最后一次骰子点数已经确定时,则只需要计算前面投了n-1次骰子,总和是s-i的情况下,一共有多少种方案。
}
return res;
}
};
#include
#include
using namespace std;
// dp方法来解决:注意三点,第一是状态的表示是什么(从输出中来)?第二是如何计算第一步中的状态?第三是边界问题
class Solution{
public:
vector numberOfDice(int n){
vector> f(n + 1, vector(n * 6 + 1)); // dp的状态表示
f[0][0] = 1; // 当所有的骰子都没有扔出时,总和s=0时,只有一种方案;总和s=1, 2, 3, 4, ....都是不合法的!
for(int i = 1; i <= n; i++){ // 先循环扔出去的次数
for(int j = 1; j <= i * 6; j++){ // 再循环总和s是多少
for(int k = 1; k <= min(j, 6); k++){ // 枚举最后一次的点数是多少
f[i][j] += f[i- 1][j - k]; // 状态f[i][j]表示前i次总和是j的方案数!
}
}
}
vector res;
for(int i = n; i <= n * 6; i++) res.push_back(f[n][i]);
return res;
}
};
#include
#include
#include
using namespace std;
// 从扑克牌中随机抽5张牌,判断是不是一个顺子。
class Solution{
public:
bool isContinous(vector& nums)
{
if(nums.empty()) return false;
sort(nums.begin(), nums.end());
int k = 0;
while(!nums[k]) k++; // 去掉行首的0
for(int i = k + 1; i < nums.size(); i++){ // 去掉重复元素
if(nums[i] == nums[i - 1]) return false;
}
return nums.back() - nums[k] <= 4;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int lastRemaining(int n, int m){
if(n == 1) return 0;
return (lastRemaining(n - 1, m) + m) % n;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int maxDiff(vector& nums)
{
if(nums.empty()) return 0;
int res = 0; // 最大利润
for(int i = 1, minValue = nums[0]; i < nums.size(); i++){
res = max(res, nums[i] - minValue); // minValue表示前i天的最小值,nums[i]表示第i天卖出的价格!
minValue = min(minValue, nums[i]);
}
return res;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int getSum(int n){
int res = n;
n > 0 && (res += getSum(n - 1)); // 实际是对if(n > 0) res += getSum(n - 1);语句的改写
return res;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int add(int num1, int num2){
while(num2){
int sum = num1 ^ num2;
int carry = (num1 & num2) << 1;
num1 = sum;
num2 = carry;
}
return num1;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
vector multiply(const vector& A){
if(A.empty()) return vector();
int n = A.size();
vector B(n);
// 先算A[0]到A[i-1]的乘积
for(int i = 0, p = 1; i < n; i++){
B[i] = p;
p *= A[i];
}
// 再算A[i+1]到A[n-1]的乘积
for(int i = n - 1, p = 1; ~i; i--){
B[i] *= p;
p *= A[i];
}
return B;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int strToInt(string str)
{
int k = 0;
while(k < str.size() && str[k] == ' ') k++; // 忽略所有的行首空格!
long long number = 0;
bool is_minus = false;
// 忽略完行首的空格后,可能有-/+的符号
if(str[k] == '+') k++;
else if(str[k] == '-') k++, is_minus = true;
while(k < str.size() && str[k] >= '0' && str[k] <= '9'){
number = number * 10 + str[k] - '0'; // 字符串表示的数字转换成真正的数字
k++;
}
if(is_minus) number *= -1; // 处理负数的情况
if(number > INT_MAX) number = INT_MAX;
if(number < INT_MIN) number = INT_MIN;
return (int)number;
}
};
#include
#include
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
if(!root) return nullptr; // 空树
if(root == p || root == q) return root;
auto left = lowestCommonAncestor(root->left, p, q); // 检查一下左边是否有p和q
auto right = lowestCommonAncestor(root->right, p, q); // 检查一下右边是否有p和q
if(left && right) return root;
if(left) return left;
return right;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int getNumberOfK(vector& nums, int k){
if(nums.empty()) return 0;
int l = 0, r = nums.size() - 1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < k) l = mid + 1;
else r = mid;
}
if(nums[l] != k) return 0;
int left = l;
l = 0, r = nums.size() - 1;
while(l < r){
int mid = l + r + 1 >> 1;
if(nums[mid] <= k) l = mid;
else r = mid - 1;
}
return r - left + 1;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int getMissingNumber(vector& nums){ // nums是输入的n-1个数
int n = nums.size() + 1;
int res = (n - 1) * n / 2;
for(auto x: nums) res -= x;
return res; // res就是0到n-1中缺失的那个数字
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int getNumberSameAsIndex(vector& nums){
int l = 0, r = nums.size() - 1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] - mid >= 0) r = mid;
else l = mid + 1;
}
if(nums[r] - r == 0) return r; // 相等元素的下标
return -1;
}
};
#include
#include
#include
#include
using namespace std;
// 二叉树的定义
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
TreeNode* ans;
TreeNode* KthNode(TreeNode* root, int k){
dfs(root, k);
return ans;
}
void dfs(TreeNode* root, int& k){
if(!root) return;
dfs(root->left, k); // 中序遍历
k--;
if(!k) ans = root;
if(k > 0) dfs(root->right, k);
}
};
#include
#include
#include
#include
using namespace std;
// 二叉树的定义
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
int treeDepth(TreeNode* root){
if(!root) return 0; // 递归终止条件!
return max(treeDepth(root->left), treeDepth(root->right)) + 1;
}
};
#include
#include
using namespace std;
// 二叉树的定义
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
bool ans = true;
bool isBalanced(TreeNode* root){
dfs(root);
return ans;
}
int dfs(TreeNode* root){
if(!root) return 0;
int left = dfs(root->left), right = dfs(root->right);
if(abs(left - right) > 1) ans = false;
return max(left, right) + 1; // 当前结点的深度 == 当前结点左右子树的深度的更大者 + 1
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
vector findNumsAppearance(vector& nums){
int sum = 0;
for(auto x : nums) sum ^= x; // 先求所有数字的异或和,也就是sum = x ^ y x,y分别表示数组中只出现一次的数字
int k = 0;
while(!(sum >> k & 1)) k++; // 然后从sum中找出其二进制表示中任意一位不为0的位,k存储的就是x ^ y结果中第k位是1的那一位
int first = 0;
for(auto x : nums){
if(x >> k & 1) // 将x的二进制表示中第k位是1的划分到第一个集合first中!
first ^= x; // 第一个集合异或的结果first 第二个结果异或的结果first ^ sum
}
return vector{first, sum ^ first};
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int findNumberAppearingOnce(vector& nums){
int ones = 0, twos = 0;
for(auto x : nums){
ones = (ones ^ x) & ~twos;
twos = (twos ^ x) & ~ones;
}
return ones;
}
};
#include
#include
#include
using namespace std;
// 暴力解法O(n**2)
class Solution{
public:
vector findNumberWithSum(vector& nums, int target){
for(int i = 0; i < nums.size(); i++){
for(int j = 0; j < i; j++){
if(nums[i] + nums[j] == target) return vector{nums[i], nums[j]};
}
}
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
vector findNumberWithSum(vector& nums, int target){
unordered_set hash;
for(int i = 0; i < nums.size(); i++){
if(hash.count(target - nums[i])) return vector{target - nums[i], nums[i]}; // hash.count(target - nums[i])就是判断nums[j]是否在j < i的范围内出现!
hash.insert(nums[i]);
}
return vector();
}
};
#include
#include
#include
using namespace std;
// 暴力方法:O(n**2)
class Solution{
public:
vector> findContinuousSequence(int sum){
vector> res;
for(int i = 1, j = 1, s = 1; i <= sum; i++) // s是当前序列的和
{
while(s < sum) s += ++j;
if(s == sum && j - i + 1 > 1){ // [i,j]中包含的元素个数是: j - i + 1
vector line;
for(int k = i; k <= j; k++) line.push_back(k); // line是一个一维数组,数组中存放的是区间[i,j]中和为s的数字
res.push_back(line);
}
s -= i;
}
return res;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
string reverseWords(string s){
reverse(s.begin(), s.end()); // 等价于for(int i = 0, j = s.size() - 1; i < j; i++, j--) swap(s[i], s[j]); 第一步首先对整个句子进行翻转
for(int i = 0; i < s.size(); i++){ // 对第一步中翻转后的每个单词进行翻转,下面是从一段字符串中提取出一个单词的操作!
int j = i;
while(j < s.size() && s[j] != ' ') j++;
reverse(s.begin() + i, s.begin() + j);
i = j;
}
return s;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
string leftRotateString(string str, int n){
reverse(str.begin(), str.end());
reverse(str.begin(), str.begin() + str.size() - n);
reverse(str.begin() + str.size() - n, str.end());
return str;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int digitAtIndex(int n){
long long i = 1, s = 9, base = 1; // i是几位数 s是几位数的个数 base是几位数的开始第一个数字
// 确定n对应是几位数
while(n > i * s){
n -= i * s;
i++;
s *= 10;
base *= 10;
}
// 确定是几位数中的哪个数
int number = base + (n + i - 1) / i - 1;
// 确定那个数的第几位
int r = n % i ? n % i : i;
for(int j = 0; j < i - r; j++) number /= 10;
return number % 10;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
static bool cmp(int a, int b){
auto as = to_string(a), bs = to_string(b);
return as + bs < bs + as;
}
string printMinNumber(vector& nums){
sort(nums.begin(), nums.end(), cmp);
string res;
for(auto x : nums) res += to_string(x);
return res;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int getTranslationCount(string s){
int n = s.size();
vector f(n+1);
f[0] = 1;
for(int i = 1; i <= n; i++){
f[i] = f[i - 1]; // 第一种情况
int t = (s[i-2] - '0') * 10 + s[i-1] - '0'; // 第二种情况
if(t >= 10 && t <= 25) f[i] += f[i-2];
}
return f[n];
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int getMaxValue(vector>& grid){
int n = grid.size(), m = grid[0].size();
vector> f(n + 1, vector(m + 1));
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
f[i][j] = max(f[i -1][j], f[i][j-1]) + grid[i-1][j-1];
}
}
return grid[n][m];
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
int lengthLongestSubString(string s){
unordered_map hash;
int res = 0;
for(int i = 0, j = 0; j < s.size(); j++){
hash[s[j]]++;
while(hash[s[j]] > 1) hash[s[i++]]--;
res = max(res, j - i + 1);
}
return res;
}
};
#include
#include
using namespace std;
class Solution{
public:
int getUglyNumber(int n){
vector q(1, 1);
int i = 0, j = 0, k = 0;
while(--n){ // 循环n-1次 while(n--){}是循环n次
int t = min(q[i] * 2, min(q[j] * 3, q[k] * 5));
q.push_back(t);
if(q[i] * 2 == t) i++;
if(q[j] * 3 == t) j++;
if(q[k] * 5 == t) k++;
}
return q.back();
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
char firstNotRepeatingChar(string s){
unordered_map hash;
for(auto c : s) hash[c]++; // 统计字符串s中每个字符出现的次数
char res = '#'; // 无解的情况
for(auto c : s)
if(hash[c] == 1){
res = c;
break;
}
return res;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
unordered_map hash;
queue q;
// 插入字符到一个队列queue中
// 利用hash表判断当前正在插入的字符是否出现在当前的队列中
void insert(char ch){
if(++hash[ch] > 1){ // 插入的字符已经出现在队列中
while(q.size() && hash[q.front()] > 1) q.pop();
}
else q.push(ch); // 插入的字符没有出现在队列中
}
char firstAppearingOnce(){
if(q.empty()) return '#';
return q.front();
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int merge(vector& nums, int l, int r){
if(l >= r) return 0;
int mid = l + r >> 1;
int res = merge(nums, l, mid) + merge(nums, mid + 1, r); // 第一和第二部分
// 第三个部分
int i = l, j = mid + 1;
vector temp;
while(i <= mid && j <= r){
if(nums[i] <= nums[j]) temp.push_back(nums[i++]);
else{
temp.push_back(nums[j++]);
res += mid - i + 1;
}
while(i <= mid) temp.push_back(nums[i++]);
while(j <= r) temp.push_back(nums[j++]);
i = l;
for(auto x : temp) nums[i++] = x;
return res;
}
}
int inversePairs(vector& nums){
int res = 0;
return merge(nums, 0, nums.size() - 1);
}
};
#include
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
using namespace std;
class Solution{
public:
ListNode* findFirstCommonNode(ListNode* headA, ListNode* headB){
auto p = headA, q = headB;
while(p != q){
if(p) p = p->next;
else p = headB;
if(q) q = q->next;
else q = headA;
}
return p;
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
vector seq;
bool verifySequenceOFBST(vector sequence){
seq = sequence;
return dfs(0, seq.size() - 1);
}
bool dfs(int l, int r){
if(l >= r) return true;
int root = seq[r];
int k = l;
while(k < r && seq[k] < root) k++; // 二叉搜索树的左子树
for(int i = k; i < r; i++){ // 判断二叉搜索树的右子树是否合法
if(seq[i] < root) return false;
}
return dfs(l, k-1) && dfs(k+1, r);
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
vector> ans;
vector path;
vector> findPath(TreeNode* root, int sum){
dfs(root, sum);
return ans;
}
void dfs(TreeNode* root, int sum){
if(!root) return; // 当前节点是空的,就不是叶子节点
path.push_back(root->val);
sum -= root->val;
// 如果当前节点的左右子树都是空的,则当前节点是叶子节点
if(!root->left && !root->right && !sum) ans.push_back(path);
// 递归处理左右子树
dfs(root->left, sum);
dfs(root->right, sum);
path.pop_back();
}
};
#include
#include
using namespace std;
struct ListNode{
int val;
ListNode* next, *random;
ListNode(int x): val(x), next(nullptr), random(nullptr){}
};
class Solution{
public:
ListNode* copyRandomList(ListNode* head){
// 第一步复制所有的节点,并将当前节点指向复制出来的节点
for(auto p = head; p;)
{
auto np = new ListNode(p->val); // 复制出来的新节点
auto next = p->next; // 备份一下p->next;
p->next = np; // 复制出来的点接在当前节点的后面
np->next = next;
p = next;
}
// 第二步复制random指针
for(auto p = head; p; p = p->next->next){
if(p->random)
p->next->random = p->random->next;
}
// 第三步将所有复制出来的节点连接起来
auto dummy = new ListNode(-1);
auto cur = dummy; // 当前新链表的尾节点
for(auto p = head; p; p = p->next){
cur->next = p->next;
cur = cur->next;
p = p->next;
}
return dummy->next;
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
TreeNode* convert(TreeNode* root){
if(!root) return nullptr;
auto sides = dfs(root);
return sides.first;
}
pair dfs(TreeNode* root){
if(!root->left && !root->right) return {root, root}; // 当前节点是叶子节点
if(root->left && root->right){
auto lsides = dfs(root->left), rsides = dfs(root->right);
lsides.second->right = root, root->left = lsides.second;
root->right = rsides.first, rsides.first->left = root;
return {lsides.first, rsides.second};
}
if(root->left){
auto lsides = dfs(root->left);
lsides.second->right = root, root->left = lsides.second;
return {lsides.first, root};
}
if(root->right){
auto rsides = dfs(root->right);
root->right = rsides.first, rsides.first->left = root;
return {root, rsides.second};
}
}
};
#include
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
// 序列化
string serialize(TreeNode* root){
string res;
dfs_s(root, res);
return res;
}
// 前序遍历实现序列化
void dfs_s(TreeNode* root, string& res){
if(!root){
res += "null ";
return;
}
res += to_string(root->val) + ' ';
dfs_s(root->left, res);
dfs_s(root->right, res);
}
// 反序列化
TreeNode* deserialize(string data){
int u = 0;
return dfs_d(data, u);
}
TreeNode* dfs_d(string data, int& u){
if(u == data.size()) return nullptr;
int k = u;
while(data[k] != ' ') k++;
if(data[u] == 'n'){ // 'n'是null的开始字符
u = k + 1;
return nullptr;
}
int val = 0;
for(int i = u; i < k; i++) val = val * 10 + data[i] - '0'; // 将字符串整数"123"转换成整数123
u = k + 1;
auto root = new TreeNode(val);
root->left = dfs_d(data, u);
root->right = dfs_d(data, u);
return root;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
vector> ans;
vector path;
vector> permutation(vector& nums){
path.resize(nums.size()); // 开辟的数组空间大小
sort(nums.begin(), nums.end());
dfs(nums, 0, 0, 0); // 用一个二进制位来表示哪些位置是空的
return ans;
}
void dfs(vector& nums, int u, int start, int state){
// u:当前枚举的位置 start: 当前这个数应该从哪个位置开始枚举?(即上一个数的后一个位置开始枚举)
// state: 存储的是状态,表示哪些数被用过
if(u == nums.size()){
ans.push_back(path);
return;
}
if(!u || nums[u] != nums[u-1]) start = 0;
for(int i = start; i < nums.size(); i++){
if(!(state >> i & 1)){ // state >> i & 1:看一下state的二进制表示中第i位是否表示为1
path[i] = nums[u];
dfs(nums, u + 1, i + 1, state + (1 << i));
}
}
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
int moreThanHalfNum(vector& nums){
int cnt = 0, val = -1;
for(auto x : nums)
{
if(!cnt) val = x, cnt = 1;
else
{
if(x == val) cnt++;
else cnt--;
}
}
return val;
}
};
#include
#include
#include
#include
using namespace std;
class Solution{
public:
vector getLeastNumbers(vector input, int k){
priority_queue heap;
for(auto x : input)
{
heap.push(x);
if(heap.size() > k) heap.pop();
}
vector res;
while(heap.size()) res.push_back(heap.top()), heap.pop(); // heap存放的是从大到小的顺序
reverse(res.rbegin(), res.rend()); // 翻转一下变成从小到大
return res;
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
priority_queue max_heap;
priority_queue, greater> min_heap;
void insert(int num){
max_heap.push(num);
if(min_heap.size() && max_heap.top() > min_heap.top())
{
auto maxv = max_heap.top(), minv = min_heap.top();
max_heap.pop(), min_heap.pop();
max_heap.push(minv), min_heap.push(maxv);
}
if(max_heap.size() > min_heap.size() + 1)
{
min_heap.push(max_heap.top());
max_heap.pop();
}
}
double getMedian(){
if(max_heap.size() + min_heap.size() & 1) return max_heap.top(); // 数据流中是奇数个数值
return (max_heap.top() + min_heap.top()) / 2.0; // 数据流中是偶数个数值
}
};
#include
#include
using namespace std;
class Solution{
public:
int maxSubArray(vector& nums){
int res = INT_MIN, s = 0;
for(auto x : nums)
{
if(s < 0) s = 0;
s += x;
res = max(res, s);
}
return res;
}
};
#include
#include
using namespace std;
class Solution{
public:
int numberOfBetween1AndN(int n){
if(!n) return 0;
vector number;
// 取出n中的每位数字放入number中
while(n)
{
number.push_back(n % 10);
n /= 10;
}
int res = 0;
for(int i = number.size() - 1; i >= 0; i--)
{
auto left = 0, right = 0, t = 1;
for(int j = number.size() - 1; j > i; j--)
{
left = left * 10 + number[j];
}
for(int j = i - 1; j >= 0; j--)
{
right = right * 10 + number[j];
t *= 10; // t表示右边一共有多少位数
}
res += left * t;
if(number[i] == 1) res += right + 1;
else if(number[i] > 1) res += t;
}
return res;
}
};
#include
#include
using namespace std;
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution{
public:
ListNode* reverseList(ListNode* head){
ListNode* pre = nullptr; // 记录当前结点的前驱结点
auto cur = head;
while(cur)
{
auto next = cur->next; // 用next变量缓存cur->next,用来使得cur向后移动一位
cur->next = pre; // 每次遍历时,将当前结点的next指针指向其前驱结点
pre = cur; // 将pre指针向后移动一位,此时pre指向cur
cur = next;
}
return pre; // pre就是反转后链表的头结点
}
};
#include
#include
using namespace std;
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution{
public:
ListNode* merge(ListNode* l1, ListNode* l2){
auto dummy = new ListNode(-1);
auto cur = dummy; // 因为往合并后的链表中添加元素时,是尾部插入的。因此,需要一个cur指针来记录当前链表的尾结点在哪。
while(l1 && l2)
{
if(l1->val < l2->val){
cur->next = l1;
cur = l1;
l1 = l1->next;
}
else{
cur->next = l2;
cur = l2;
l2 = l2->next;
}
}
// 将两个链表中更长者中剩余的部分链接到已合并链表的末尾
if(l1) cur->next = l1;
else cur->next = l2;
return dummy->next;
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
bool hasSubTree(TreeNode* pRoot1, TreeNode* pRoot2){
if(!pRoot1 || !pRoot2) return false;
// 前序遍历树pRoot1,然后与pRoot2结点进行对比
if(isPart(pRoot1, pRoot2)) return true;
return hasSubTree(pRoot1->left, pRoot2) || hasSubTree(pRoot1->right, pRoot2);
}
bool isPart(TreeNode* p1, TreeNode* p2){
if(!p2) return true;
if(!p1 || p1->val != p2->val) return false;
return isPart(p1->left, p2->left) && isPart(p1->right, p2->right);
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
void mirror(TreeNode* root){
if(!root) return;
mirror(root->left);
mirror(root->right);
swap(root->left, root->right);
}
};
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
bool isSymmetric(TreeNode* root){
if(!root) return true;
return dfs(root->left, root->right);
}
bool dfs(TreeNode* p, TreeNode* q){
if(!p || !q) return !p && !q;
if(p->val != q->val) return false;
return dfs(p->left, q->right) && dfs(p->right, q->left);
}
};
#include
#include
using namespace std;
class Solution{
public:
vector printMatrix(vector> matrix){
vector res;
int n = matrix.size(), m = matrix[0].size();
if(!n) return res;
vector> st(n, vector(m, false)); // 二维数组记录每个格子是否被访问过
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 上 右 下 左
int x = 0, y = 0, d = 1; // 起始方向是向右移动,故d = 1
for(int i = 0; i < n * m; i++)
{
res.push_back(matrix[x][y]);
st[x][y] = true; // 当前点被标记成已经访问
int a = x + dx[d], b = y + dy[d]; // 下一个点的坐标
if(a < 0 || a >= n || b < 0 || b >= m || st[a][b]){ // 当前点已经出界或者被访问过
d = (d + 1) % 4; // d向下移动
a = x + dx[d], b = y + dy[d];
}
}
return res;
}
};
#include
#include
#include
using namespace std;
class MinStack{
public:
stack stk, min_stk; // stk是主栈 min_stk是单调栈
MinStack(){
}
void push(int x){
stk.push(x);
if(min_stk.empty() || min_stk.top() >= x) min_stk.push(x);
}
void pop(){
if(stk.top() == min_stk.top()) min_stk.pop();
stk.pop();
}
int top(){
return stk.top();
}
int getMin(){
return min_stk.top();
}
};
#include
#include
#include
using namespace std;
class Solution{
public:
bool isPopOrder(vector pushV, vector popV){
if(popV.size() != pushV.size()) return false;
stack s;
int index = 0;
for(int i = 0; i < pushV.size(); i++){
s.push(pushV[i]);
while(!s.empty() && s.top() == popV[index]){
s.pop();
index++;
}
}
if(s.empty()) return true;
return false;
}
};
#include
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
vector printFromTopToBottom(TreeNode* root){
vector res;
if(!root) return res;
queue q;
q.push(root);
while(q.size())
{
auto t = q.front();
q.pop();
res.push_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};
#include
#include
#include
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
vector> printFromTopToBottom(TreeNode* root){
vector> res;
if(!root) return res;
queue q;
q.push(root);
q.push(nullptr);
vector level; // 辅助的数组表示每层中有多少个结点
while(q.size()){
auto t = q.front(); // 队首元素
q.pop();
if(!t) // t为空时,表示已经遍历完一层
{
if(level.empty()) break; // level数组为空时,表示已经遍历完所有的结点,就直接返回
res.push_back(level);
level.clear();
q.push(nullptr);
continue;
}
level.push_back(t->val); // t不为空时,将当前的点加入到level中,进行扩展
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};
class Solution{
public:
vector> printFromTopToBottom(TreeNode* root){
vector> res;
if(!root) return res;
queue q;
q.push(root);
q.push(nullptr);
vector level; // 辅助的数组表示每层中有多少个结点
bool zigzag = false; // 表示从左到右打印
while(q.size()){
auto t = q.front(); // 队首元素
q.pop();
if(!t) // t为空时,表示已经遍历完一层
{
if(level.empty()) break; // level数组为空时,表示已经遍历完所有的结点,就直接返回
if(zigzag) reverse(level.begin(), level.end());
res.push_back(level);
level.clear();
q.push(nullptr);
zigzag = !zigzag;
continue;
}
level.push_back(t->val); // t不为空时,将当前的点加入到level中,进行扩展
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
return res;
}
};
class Solution
{
public:
// 算出一个数字的各个位置上的数字之和
int get_single_sum(int x){
int s = 0;
while(x)
{
s += x % 10;
x /= 10;
}
return s;
}
// 算出一个格子中的各个位置上数字之和
int get_sum(pair p){
return get_single_sum(p.first) + get_single_sum(p.second); // p.first是x坐标 p.second是y坐标
}
int movingcount(int threshold, int rows, int cols){
int res = 0;
if(!rows || !cols) return 0;
vector> st(rows, vector (cols, false)); // 全部初始化成false,记录每个格子是否已经被访问
queue> q;
q.push({0, 0}); // 初始坐标初始化
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; // 顺时针来记忆 上 右 下 左
while(q.size()){
auto t = q.front();
q.pop();
if(get_sum(t) > threshold || st[t.first][t.second]) continue;
res++;
st[t.first][t.second] = true;
for(int i = 0; i < 4; i++)
{
int x = t.first + dx[i], y = t.second + dy[i];
if(x >= 0 && x < rows && y >= 0 && y < cols){
q.push({x, y});
}
}
}
return res;
}
};
class Solution
{
public:
int maxProductAfterCutting(int n){
if(n <= 3) return 1 * (n-1);
int res = 1;
if(n % 3 == 1) res *= 4, n -= 4; // 拆成出来两个2
if(n % 3 == 2) res *= 2, n -= 2; // 拆出来一个2
while(n) res *= 3, n -= 3; // 拆出来全部都是3
return res;
}
};
class Solution
{
public:
int numberOf1(int _n){
unsigned int n = _n; // 将有符号数转换成无符号数,为了下面的循环
int s = 0;
while(n)
{
s += n & 1; // 每次将n的个位取出来,判断是否是1,是1的话就s++
n >> 1; // 然后将n的个位移除,即n右移一位
}
return s;
}
};
class Solution
{
public:
double Power(double base, int exponent){
double res = 1;
for(int i = 0; i < abs(exponent); i++){
res *= base;
}
if(exponent < 0) res = 1 / res;
return res;
}
};
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution
{
public:
void deleteNode(ListNode* node){
node->val = node->next->val;
node->next = node->next->next;
}
};
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution{
public:
ListNode* deleteDuplication(ListNode* head){
auto dummy = new ListNode(-1);
dummy->next = head;
auto p = dummy;
while(p->next)
{
auto q = p->next;
while(q && p->next->val == q->val){
q = q->next;
}
if(p->next->next == q) p = p->next; // 下一段的长度是1,没有重复结点,不用删
else p->next = q; // 下一段的长度超过1,则删除重复结点
}
return dummy->next;
}
};
class Solution{
public:
int n, m;
vector> f;
string s, p;
bool inMatch(string _s, string _p){
s = _s, p = _p;
n = s.size(), m = p.size();
f = vector> (n + 1, vector(m + 1, -1));
return dp(0, 0);
}
bool dp(int x, int y){
if(f[x][y] != -1) return f[x][y];
if(y == m)
return f[x][y] = x == n;
bool first_match = x < n && (p[y] == '.' || s[x] == p[y]); // 情况1和情况2
if(y + 1 < m && p[y + 1] == '*'){ // 情况3
f[x][y] = dp(x, y + 2) || dp(x + 1, y);
}
else{
f[x][y] = first_match && dp(x + 1, y + 1);
}
return f[x][y];
}
};
class Solution{
public:
bool isNumber(string s){
int i = 0, j = s.size();
// 删除字符串s中的前后空格
while(i <= j && s[i] == ' ') i++;
while(i <= j && s[j] == ' ') j--;
if(i > j) return false;
s = s.substr(i, j - i + 1);
if(s[0] == '+' || s[0] == '-') s = s.substr(1);
if(s.empty() || (s[0] == '.' && s.size() == 1)) return false; // + - .
int dot = 0, e = 0; // 统计有多少个.和e
for(int i = 0; i < s.size(); i++){
if(s[i] >= '0' && s[i] <= '9');
else if(s[i] == '.'){
dot++;
if(dot > 1 || e) return false; // 3434.23232.4343, 23232e23232.2323
}
else if(s[i] == 'e' || s[i] == 'E'){
e++;
if(!i || i + 1 == s.size() || e > 1 || s[i - 1] == '.' && i == 1) return false; // e1223233, 11232e, 1212e32323e
if(s[i + 1] == '+' || s[i + 1] == '-'){
if(i + 2 == s.size()) return false; // 12341e+
i++;
}
}
else return false;
}
return true;
}
};
class Solution{
public:
void reOrderArray(vector& nums){
int first = 0, second = nums.size() - 1;
while(first <= second){
while(first <= second && nums[first] % 2 == 1) first++;
while(first <= second && nums[second] % 2 == 0) second--;
if(first < second) swap(nums[first], nums[second]);
}
}
};
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution{
public:
ListNode* findKthToTail(ListNode* head, int k){
int n = 0;
for(auto p = head; p; p = p->next) n++;
if(k > n) return nullptr;
auto p = head;
for(int i = 0; i < n - k; i++) p = p->next;
return p;
}
};
struct ListNode{
int val;
ListNode* next;
ListNode(int x): val(x), next(nullptr){}
};
class Solution{
public:
ListNode* entryNodeOfLoop(ListNode* head){
auto i = head, j = head; // i是慢指针,每次走一步;j是快指针,每次走两步
while(i && j){
i = i->next;
j = j->next;
if(j) j = j->next;
if(i == j){ // i和j相遇了
i = head; // 慢指针i回到起点
while(i != j){ // 慢指针和快指针同时向后移动一个位置
i = i->next;
j = j->next;
}
return i; // 环入口的位置
}
}
return nullptr; // 无环存在
}
};
class Solution{
public:
int duplicateInArray(vector& nums){
for(auto x : nums){
if(x < 0 || x >= nums.size())
return -1;
}
for(int i = 0; i < nums.size(); i++){
while(i != nums[i] && nums[nums[i]] != nums[i]) swap(nums[i], nums[nums[i]]);
if(nums[i] != i && nums[nums[i]] == nums[i]) return nums[i];
}
return -1;
}
};
class Solution{
public:
int duplicateInArray(vector& nums){
int l = 1, r = nums.size() - 1;
while(l < r){
int mid = l + r >> 1; // [l, mid], [mid + 1, r]
int s = 0; // 统计元素的个数
for(auto x : nums) s += x >= l && x <= mid;
if(s > mid - l + 1) r = mid;
else l = mid + 1;
}
return r;
}
};
class Solution{
public:
bool searchArray(vector> array, int target){
if(array.empty() || array[0].empty()) return false;
int i = 0, j = array[0].size() - 1;
while(i < array.size() && j >=0){
if(array[i][j] == target) return true;
if(array[i][j] > target) j--;
else i++;
}
return false;
}
};
class Solution{
public:
string replaceSpaces(string& str){
string res;
for(auto x : str){
if(x == ' ')
res += "20%";
else res += x;
}
return res;
}
};
class Solution{
public:
vector printListReversingly(ListNode* head){
vector res;
while(head){
res.push_back(head->val);
head = head->next;
}
return vector(res.rbegin(), res.rend());
}
};
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(nullptr), right(nullptr){}
};
class Solution{
public:
map hash; // 开一个hash表,记录每个节点在数组中的位置
vector preorder, inorder;
TreeNode* buildTree(vector& _preorder, vector& _inorder){
preorder = _preorder, inorder = _inorder;
for(int i = 0; i < inorder.size(); i++){
hash[inorder[i]] = i;
}
return dfs(0, preorder.size() - 1, 0, inorder.size() - 1);
}
TreeNode* dfs(int pl, int pr, int il, int ir){
if(pl > pr) return nullptr;
auto root = new TreeNode(preorder[pl]);
int k = hash[inorder[root->val]];
auto left = dfs(pl + 1, pl + 1 + k - il - 1, il, k - 1);
auto right = dfs(pl + k - il + 1, pr, k + 1, ir);
root->left = left;
root->right = right;
return root;
}
};
class Solution{
public:
TreeNode* inorderSuccessor(TreeNode* p){
if(p->right){ // 情况1
p = p->right;
while(p->left) p = p->left;
return p;
}
// 情况2
while(p->father && p == p->father->right) p = p->father;
return p->father;
}
};
class MyQueue{
public:
stack stk, cache;
MyQueue(){
}
void push(int x){
stk.push(x);
}
// 辅助函数
void copy(stack& a, stack& b){
while(a.size()){
b.push(a.top());
a.pop();
}
}
int pop(){
copy(stk, cache);
int res = cache.top();
cache.pop();
copy(cache, stk);
return res;
}
int peak(){
copy(stk, cache);
int res = cache.top();
copy(cache, stk);
return res;
}
bool empty(){
return stk.empty();
}
};
class Solution{
public:
int Fibonacci(int n){
int a = 0, b = 1;
while(n--){
int c = a + b;
a = b, b = c;
}
return a;
}
};
class Solution{
public:
int findMin(vector& nums){
int n = nums.size() - 1;
if(n < 0) return -1;
while(n > 0 && nums[n] == nums[0]) n--; // 去掉后半部分相等的数值
if(nums[n] >= nums[0]) return nums[0];
int l = 0, r = n;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}
};
class Solution{
public:
bool hasPath(vector>& matrix, string str){
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < matrix[0].size(); j++){
if(dfs(matrix, str, 0, i, j)) // 枚举所有起点i, j,从字符串str第0个字符串开始枚举
return true;
}
}
return false;
}
bool dfs(vector>& matrix, string& str, int u, int x, int y){ // 当前字符串str中的第几个字符u,x和y是当前路径的坐标
if(u == str.size()) return true;
if(matrix[x][y] != str[u]) return false;
// 枚举四个方向
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
char t = matrix[x][y]; // 已经访问过的字符,不能重新访问
matrix[x][y] = '*';
for(int i = 0; i < 4; i++){
int a = x + dx[i], b = y + dx[i];
if(a >= 0 && a < matrix.size() && b >= 0 && b < matrix[a].size()){
if(dfs(matrix, str, u + 1, a, b)) return true;
}
}
matrix[x][y] = t;
return false;
}
};