
class Solution {
public:
string reverseWords(string s) {
int front = 0, back = 0;
for(int i = 0; i < s.size(); i ++)
{
if(s[i] != ' ') back ++;
else
{
reverse(s.begin() + front, s.begin() + back);
front = back + 1;
back = front;
}
}
reverse(s.begin() + front, s.begin() + back);
return s;
}
};
class Solution {
public:
string reverseWords(string s) {
int n = s.size();
int start = 0, back = 0;
for(int i = 0; i < n + 1; i ++)
{
if(s[i] == ' ' || s[i] == '\0')
{
for(back = i - 1; start < back; start ++, back --)
swap(s[start], s[back]);
start = i + 1;
}
}
return s;
}
};

class Solution {
public:
int maxDepth(Node* root) {
if(!root) return 0;
int d = 1;
for(auto s : root->children)
d = max(d, maxDepth(s) + 1);
return d;
}
};

class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int>hash;
hash[0] = 1;
int res = 0, s = 0;
for(auto x : nums)
{
s += x;
res += hash[s - k];
hash[s] ++;
}
return res;
}
};

class Solution {
public:
int arrayPairSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
int res = 0;
for(int i = 0; i < nums.size(); i += 2)
res += min(nums[i], nums[i + 1]);
return res;
}
};

class Solution {
public:
int findTilt(TreeNode* root) {
int res = 0;
dfs(root, res);
return res;
}
int dfs(TreeNode* root, int &res)
{
if(!root) return 0;
int left = dfs(root->left, res);
int right = dfs(root->right, res);
res += abs(left - right);
return root->val + left + right;
}
};

class Solution {
public:
string nearestPalindromic(string n) {
long long N = stol(n), len = n.size();
set<long long>s;
s.insert(pow(10, len) + 1);
s.insert(pow(10, len - 1) - 1);
long long prefix = stol(n.substr(0, (len + 1) / 2));
for(int i = -1; i <= 1; i++)
{
string pre = to_string(prefix + i);
s.insert(stol(pre + string(pre.rbegin() + (len & 1), pre.rend())));
}
s.erase(N);
long long res = -1, min = LLONG_MAX;
for(auto val : s)
{
long long diff = abs(N - val);
if(diff < min)
{
min = diff;
res = val;
}
}
return to_string(res);
}
};

class Solution {
public:
int arrayNesting(vector<int>& nums) {
int res = 0;
for(int i = 0; i < nums.size(); i ++)
{
int start = nums[i], count = 0;
if(nums[i] == -1) continue;
nums[i] = -1;
do{
start = nums[start];
count ++;
}while(start != nums[i]);
res = max(res, count);
}
return res;
}
};
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int res = 0;
for(int i = 0; i < nums.size(); i ++)
{
if(nums[i] != -1)
{
int start = nums[i], count = 0;
while(nums[start] != -1)
{
int tmp = start;
start = nums[start];
count ++;
nums[tmp] = -1;
}
res = max(res, count);
}
}
return res;
}
};


class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
int n = nums.size(), m = nums[0].size();
if(r * c != n * m) return nums;
vector<vector<int>>res(r, vector<int>(c));
for(int i = 0; i < n * m; i ++)
res[i / c][i % c] = nums[i / m][i % m];
return res;
}
};

class Solution {
public:
bool checkInclusion(string s1, string s2) {
if(s1.size() > s2.size()) return false;
int windowSize = s1.size();
vector<int>hash1(26, 0);
vector<int>hash2(26, 0);
for(int i = 0; i < windowSize; i ++)
{
hash1[s1[i] - 'a'] ++;
hash2[s2[i] - 'a'] ++;
}
for(int i = windowSize; i < s2.size(); i ++)
{
if(hash1 == hash2) return true;
hash2[s2[i - windowSize] - 'a'] --;
hash2[s2[i] - 'a'] ++;
}
return hash1 == hash2;
}
};


class Solution {
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
if(s == NULL && t == NULL) return true;
if(s == NULL && t != NULL) return false;
return isSametree(s, t) || isSubtree(s->left, t) || isSubtree(s->right, t);
}
bool isSametree(TreeNode*s, TreeNode* t)
{
if(s == NULL && t == NULL) return true;
return s && t && (s->val == t->val)
&& isSametree(s->left, t->left)
&& isSametree(s->right, t->right);
}
};

class Solution {
public:
int distributeCandies(vector<int>& candies) {
set<int> s(candies.begin(), candies.end());
return min(s.size(), candies.size() >> 1);
}
};
class Solution {
public:
int distributeCandies(vector<int>& candies) {
unordered_map<int, int>hash;
for(int x : candies)
hash[x] ++;
return min(hash.size(), candies.size() >> 1);
}
};