class Solution {
public:
int majorityElement(vector<int>& nums)
{
//候选人算法——根据众数进行pk
int candidate = nums[0];
int get_count = 0;
for(auto e : nums)
{
if(candidate == e)
get_count++;
else
get_count--;
if(get_count == 0)
{
candidate = e;
get_count = 1;
}
}
return candidate;
}
};
class Solution {
public:
int Add(int num1, int num2)
{
int begin = num1;
int add = num2;
int end;
while(add)
{
end = begin ^ add;
add = ((begin & add)<<1);
begin = end;
}
return begin;
}
};
class Solution {
public:
int exchangeBits(int num)
{
int Odd = num & 0xaaaaaaaa;//奇数位
int Even = num & 0x55555555;//偶数位
int res = (Odd>>1) ^ (Even << 1);
return res;
}
};
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums)
{
vector<int> ret;
int n = nums.size();
for (auto e : nums)
{
int x = e % (n + 1);
nums[x-1] += ( n + 1);
}
for(int i = 0 ; i < n; i++)
{
if(nums[i] <= n)
ret.push_back(i+1);
}
return ret;
}
};
class Solution {
public:
vector<int> masterMind(string solution, string guess)
{
vector<int> ret(2);
map<char, int> sol;
map<char, int> gue;
//先考虑是否真猜中了
for(int i = 0; i < 4; i++)
{
if(solution[i] == guess[i])
{
ret[0]++;
}
else
{
//没猜中,记录猜的槽位颜色出现的次数,用于判断是否伪猜中。
sol[solution[i]]++;
gue[guess[i]]++;
}
}
for(auto e : gue)
{
//gue的槽位颜色在sol出现,即为伪猜中。
if(sol[e.first] != 0)
{
//伪猜中的肯定是最小次数。
ret[1] += min(sol[e.first],e.second);
}
}
return ret;
}
};
class Solution {
public:
int trailingZeroes(int n)
{
int sum = 0;
long long k = 5;
while(1)
{
if(n / k)
sum += n/k;
else
break;
k*=5;
}
return sum;
}
};
#include
#include
#define MAX 1000000
using namespace std;
int main()
{
vector<int> dp(MAX + 1);
dp[1] = 1,dp[2] = 2;
for(int i = 3; i <= MAX; i++)
{
dp[i] = 2 * dp[i-1] + dp[i-2];
dp[i] %= 32767;
}
int n;
cin >> n;
while(n--)
{
int k;
cin>>k;
cout << dp[k]<<endl;
}
return 0;
}
lass Solution {
public:
int findLHS(vector<int>& nums)
{
unordered_map<int,int> last;
int n = nums.size();
for(int i = 0; i < n; i++)
{
last[nums[i]]++;
}
int len = 0;
for(auto e : nums)
{
if(last[e] && last[e+1])
{
int n = last[e] + last[e+1];
len = len > n ? len : n;
}
}
return len;
}
};
class SnapshotArray {
public:
int _id = 0;
unordered_map<int,map<int,int>> arr;
//index, _id, val。索引值是递增的,因此用map排序较为合适
SnapshotArray(int length) {}
void set(int index, int val)
{
arr[index][_id] = val;
//记录索引值对应快照号的值。
}
int snap()
{
return _id++;
}
int get(int index, int snap_id)
{
//先看index在arr中存不存在
auto is_find = arr.find(index);
if(is_find == arr.end())
return 0; //不存在说明为初始值——0
//如果snap_id对应的数组的值没有被修改,就还是以前快照的snap_id
//修改了就是当前的snap_id
//因此找到比snap_id大的前一个即可
auto it = arr[index].upper_bound(snap_id);
//如果it等于begin说明前面没有小于等于snap_id的
return it == arr[index].begin() ? 0 : (--it)->second;
}
};
偷个懒,直接用库里的了:
class LRUCache {
public:
LRUCache(int capacity)
{
_capacity = capacity;
_sz = 0;
}
int get(int key)
{
//存在缓存的条件是:1.key能在哈希表中找到。
auto it = kv.find(key);
if(it != kv.end())
{
//因为要从缓存中获取所以要更新key所在缓存k的位置。
auto del = ki[key];
k.push_back(key);
k.erase(del);
auto last = --k.end();
ki[key] = last;
return it->second;
}
return -1;
}
void put(int key, int value)
{
//如果不存在
auto is_find = kv.find(key);
if(is_find == kv.end())
{
//看k的容量是否满了。
if(_sz == _capacity)
{
_sz--;
//把哈希表存位置的信息删除
auto del_1 = k.begin();
int key = *del_1;
ki.erase(key);
//把这个结点删除了。
k.erase(del_1);
//把kv的信息删除了
auto del_2 = kv.find(key);
kv.erase(del_2);
}
//在缓存中添上这个值
k.push_back(key);
//在存放缓存的信息的表中存放这个值
auto last = --k.end();
ki[key] = last;
_sz++;
}
else
{
auto it = kv.find(key);
if(it != kv.end())
{
//因为要从缓存中获取所以要更新key所在缓存k的位置。
auto del = ki[key];
k.push_back(key);
k.erase(del);
auto last = --k.end();
ki[key] = last;
}
}
kv[key] = value;
}
list<int> k;
unordered_map<int,int> kv;
unordered_map<int,list<int>::iterator> ki;
int _sz,_capacity;
};
#include
class Solution {
public:
bool judge(vector<int>& nums, int x)
{
int n = nums.size();
//处理特殊情况
if(n == 1)
return true;
//处理边界情况
if(x == 0)
return nums[1] < nums[0];
if(x == n-1)
return nums[n-2] < nums[n-1];
//正常判断
if(nums[x] > nums[x-1] && nums[x] > nums[x+1])
return true;
else
return false;
}
bool is_up(vector<int>& nums, int x)
{
//x值处于上升趋势,严格递增。
if(nums[x] > nums[x-1] && nums[x] < nums[x+1])
return true;
else
return false;
}
int findPeakElement(vector<int>& nums)
{
int left = 0,right = nums.size() - 1,mid = (right + left) / 2;
while(left <= right)
{
if(judge(nums,mid))
return mid;
else
{
if(is_up(nums,mid))
left = mid + 1;
else
right = mid - 1;
}
mid = (right + left) / 2;
}
//如果找不到
return -1;
}
};
class Solution
{
public:
void judge(vector<int>& ages,unordered_map<int,int>& count,\
int& cnt)
{
int sz = ages.size();
count[ages[0]]++;
for(int i = 1; i < sz; i++)
{
count[ages[i]]++;
//二分查找
int left = 0,right = i - 1;
while(left < right)
{
int mid = (left + right) / 2;
if(ages[mid] * 2 > ages[i] + 14)
{
//发送请求[mid,right]是适龄好友
right = mid;
}
else
{
//不能发送请求[left,mid]不是适龄好友
left = mid + 1;
}
}
//[left,right]区间可能都不是适龄好友。
//所以只需判断left或者right(left == right)是否是适龄好友即可
if(ages[left] * 2 > ages[i] + 14)
{
//是适龄好友,那么就加上区间[left,i)的个数即可。
cnt += (i - left);
//相等是一种特殊的情况,可以互发因此多发一次。
cnt += (count[ages[i]] - 1);
}
}
}
int numFriendRequests(vector<int>& ages)
{
vector<int> youngth;
unordered_map<int,int> count;
//进行排升序。
sort(ages.begin(),ages.end());
int cnt = 0;
judge(ages,count,cnt);
return cnt;
}
};
class Solution {
public:
int searchInsert(vector<int>& nums, int target)
{
int left = 0,right = nums.size() -1;
while(left <= right)
{
int mid = (left + right) / 2;
if(nums[mid] >= target)
right = mid - 1;
else
left = mid + 1;
}
return left;
}
};
class Solution {
public:
int search(vector<int>& nums, int target)
{
int left = 0, right = nums.size() -1;
while(left <= right)
{
int mid = (left + right) / 2;
//判断顺序区间
if(nums[mid] >= nums[left])
{
//左区间是顺序区间
//判断target是否在顺序区间。
(target >= nums[left] && target < nums[mid]) ? \
right = mid - 1:\
left = mid + 1;
}
else
{
//右区间是顺序区间
(target <= nums[right] && target > nums[mid]) ? \
left = mid + 1 :\
right = mid - 1;
}
if(nums[mid] == target)
return mid;
}
return -1;
}
};
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums)
{
int n = nums.size();
//多开辟一个元素,存右侧乘积
vector<int> ret(n+1);
//因为0下标没有左侧元素,因此设为1
ret[0] = 1;
for(int i = 1; i < n; i++)
{
ret[i] = ret[i-1] * nums[i-1];
}
//右侧元素的乘积,顺便求一下所求。
//因为n-1右侧没有元素,因此设为1
ret[n] = 1;
for(int i = n - 1; i >= 0; i--)
{
//所求等于左侧元素乘以右侧元素。
ret[i] = ret[i]*ret[n];
ret[n]*= nums[i];
}
ret.resize(n);
return ret;
}
};
#include
#include
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target)
{
multimap<int,int> m;
int n = numbers.size();
for(int i = 0 ; i < n; i++)
{
m.insert(make_pair(numbers[i],i));
}
auto begin = m.begin();
auto end = --m.end();
while(true)
{
if(begin->first + end->first >target)
end--;
else if(begin->first + end->first < target)
begin++;
else
break;
}
vector<int> v(2);
v[0] = begin->second + 1;
v[1] = end->second + 1;
if(v[0] > v[1])
swap(v[0],v[1]);
return v;
}
};
class Solution {
public:
vector<int> sortArrayByParityII(vector<int>& nums)
{
//双指针算法
int i = 0 , j = 1;
//i维护偶数区间,j维护奇数区间
int sz = nums.size();
cout << i << endl;
for( ; i < sz; i += 2)
{
if(nums[i] % 2 != 0)
{
while(nums[j] % 2 != 0)
j += 2;
swap(nums[i],nums[j]);
}
}
return nums;
}
};
class Solution {
public:
string makeGood(string s)
{
stack<char> st;
st.push(s[0]);
int n = s.size();
for(int i = 1; i < n; i++)
{
if(!st.empty() && (abs(st.top() - s[i]) == 32))
st.pop();
else
st.push(s[i]);
}
string ret;
while(!st.empty())
{
ret+=st.top();
st.pop();
}
reverse(ret.begin(),ret.end());
return ret;
}
};
class Solution {
public:
string multiply(string num1, string num2)
{
if(num1 == "0" || num2 == "0")
return "0";
int len1 = num1.size();
int len2 = num2.size();
vector<short> ret(len1 + len2,0);
int mod = 0;
for(int i = len1 - 1; i > -1; i--)
{
//[len2,len1 + len2 - 1]
int pos = len2 + i;
int n1 = num1[i] - '0';
if(n1 || mod)
{
if(n1)
{
for(int j = len2 - 1; j > -1; j--)
{
int n2 = num2[j] - '0';
if(n2 || mod)
{
int product = n1 * n2 + mod;
int add = product % 10;
mod = product / 10;
ret[pos] += add;
mod += ret[pos] / 10;
ret[pos] %= 10;
}
pos--;
}
}
if(mod)
{
ret[pos] += mod;
mod = ret[pos] / 10;
ret[pos] %= 10;
}
}
}
string product;
int i = ret[i] == 0 ? 1 : 0;
for( ; i < len1 + len2; i++)
{
product += to_string(ret[i]);
}
return product;
}
};
class Solution {
public:
ListNode* removeZeroSumSublists(ListNode* head)
{
ListNode* newhead = new ListNode(0);
unordered_map<int,ListNode*> pos;
newhead->next = head;
int sum = 0;
//思路:
//前缀和相等——说明之间的区间相加等于0。范围是( ]
//为了跳过这一段区间,我们得记录最后一个前缀和相等的结点。
//只需要更新结点的下一个位置到最后一个前缀和相等的下一个位置即可。
for(ListNode* cur = newhead; cur; cur = cur->next)
{
sum += cur->val;
pos[sum] = cur;
}
sum = 0;
for(ListNode* cur = newhead; cur; cur = cur->next)
{
sum += cur->val;
cur->next = pos[sum]->next;
}
return newhead->next;
}
};
迭代:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n)
{
//非递归——空间复杂度为O(1)
ListNode* newhead = head;
ListNode* pprev = head;
ListNode* prev = head,*cur = nullptr,*next = nullptr;
if(prev)
cur = prev->next;
if(cur)
next = cur->next;
int m1 = m;
while(--m1)
{
pprev = prev;
prev = prev->next;
if(prev)
cur = prev->next;
if(cur)
next = cur->next;
}
int x = n - m ;
ListNode *last = prev;
while(x--)
last = last->next;
if(pprev == prev)
newhead = last;
else
pprev->next = last;
last = last->next;
int count = n - m;
//指向n+1位置的结点
prev->next = last;
while(count--)
{
cur->next = prev;
prev = cur;
cur = next;
if(next)
next = next->next;
}
return newhead;
}
};
递归:
class Solution
{
public:
void Reverse(ListNode* prev, ListNode* cur, int count)
{
if(count == 0)
return;
Reverse(cur,cur->next,count-1);
cur->next = prev;
}
ListNode* reverseBetween(ListNode* head, int m, int n)
{
//可以用递归试一下
ListNode* cur = head, *prev = cur;
ListNode* Head;
int m1 = m;
while(--m1)
{
prev = cur;
cur = cur->next;
}
//找到 2 1
ListNode* last = cur;
int x = n - m;
while(x--)
last = last->next;
if(cur != prev)
{
prev->next = last;
Head = head;
}
else
Head = last;
last = last->next;
Reverse(last,cur,n - m + 1);
return Head;
}
};
class Solution {
public:
int PrevOrder(TreeNode* root, vector<int>& v)
{
if(root == NULL)
return 0;
int left_sum = PrevOrder(root->left,v);
int right_sum = PrevOrder(root->right,v);
v.push_back(abs(left_sum - right_sum));
return left_sum + right_sum + root->val;
}
int findTilt(TreeNode* root)
{
vector<int> v;
PrevOrder(root,v);
int sum = 0;
int n = v.size();
for(int i = 0; i < n; i++)
{
sum += v[i];
}
return sum;
}
};
class Solution {
public:
void PrevOrder(TreeNode*root ,vector<int>& v, int val)
{
if(root == nullptr)
return;
val = (val << 1) ^ (root->val);
if(root->left == nullptr && root->right == nullptr)
{
v.push_back(val);
return;
}
PrevOrder(root->left,v,val);
PrevOrder(root->right,v,val);
}
int sumRootToLeaf(TreeNode* root)
{
int i = 0;
vector<int> v;
PrevOrder(root, v, i);
int sum = 0;
int n = v.size();
for(int i = 0; i < n; i++)
{
sum+=v[i];
}
return sum;
}
};
class Solution {
public:
TreeNode* AfterOrder(TreeNode* root)
{
if(root == NULL)
return NULL;
TreeNode* left = AfterOrder(root->left);
TreeNode* right = AfterOrder(root->right);
//一侧和两端
if((left && right) \
||(root == P && (left == Q || right == Q))\
||(root == Q &&(left == P || right == P)))
Root = root;
//根节点可能是P或者Q
if(root == P || root == Q)
return root;
//剩余的情况肯定是两侧都为空,或者有一个不为空。
return left != NULL ? left : right;
}
TreeNode* lowestCommonAncestor(TreeNode* root, \
TreeNode* p, TreeNode* q)
{
P = p;
Q = q;
AfterOrder(root);
return Root;
}
TreeNode* P;
TreeNode* Q;
TreeNode* Root;
};
class Solution {
public:
void InOrder(TreeNode* root,TreeNode*& prev)
{
if(root == nullptr)
return;
InOrder(root->left,prev);
//根
//根节点的左指针指向前驱。
root->left = prev;
//根节点的右指针指向后驱。
if(prev)
prev->right = root;
//更新前一个节点
prev = root;
InOrder(root->right,prev);
}
TreeNode* Convert(TreeNode* root)
{
TreeNode* prev = nullptr;
InOrder(root, prev);
while(root && root->left)
{
root = root->left;
}
return root;
}
};
class Solution {
public:
string multiply(string num1, string num2)
{
//串行乘法器的实现
//先实现每个数的与乘数的乘积
//补上后缀0.
//再实现加法运算。
vector<string> num;
int sz = num2.size();
int zero = 0;
for(int i = sz - 1; i > -1; i--)
{
if(num2[i] == '0')
{
num.push_back("0");
zero++;
}
else
{
string str;
int mod = 0;
int sz = num1.size();
for(int j = sz - 1; j > -1; j--)
{
int n1 = num1[j] - '0';
int n2 = num2[i] - '0';
int add = (n1 * n2 + mod) % 10;
mod = (n1 * n2 + mod) / 10;
str += to_string(add);
}
//最后看有没有余数
if(mod)
str += to_string(mod);
reverse(str.begin(),str.end());
//再加后缀0
int tmp = zero;
while(tmp != 0)
{
str += to_string(0);
--tmp;
}
zero++;
//最后放入vector。
if(str[0] != '0')
num.push_back(str);
else
num.push_back("0");
}
}
//将字符串进行相加。
sz = num.size();
string sum = num[0];
for(int i = 1; i < sz; i++)
{
string n1 = num[i];
int sz1 = n1.size();
int sz2 = sum.size();
int mod = 0;
string ret;
while(sz1 || sz2)
{
int add1 = sz1 == 0 ? 0 : n1[sz1-1] - '0';
int add2 = sz2 == 0 ? 0 : sum[sz2 -1] - '0';
int end = (add1 + add2 + mod) % 10;
mod = (add1 + add2 + mod) / 10;
ret += to_string(end);
if(sz1)
sz1--;
if(sz2)
sz2--;
}
if(mod)
ret+=to_string(mod);
reverse(ret.begin(),ret.end());
sum = ret;
}
return sum;
}
};
class Solution {
public:
struct Greater
{
bool operator()(const pair<char,int>& n1,const pair<char,int>& n2)
{
return n1.second > n2.second;
}
};
int leastInterval(vector<char>& tasks, int n)
{
map<char,int>count;
for(auto e : tasks)
count[e]++;
vector<pair<char,int>> s(count.begin(),count.end());
stable_sort(s.begin(),s.end(),Greater());
vector<int> t;
for(const auto& e : s)
{
t.push_back(e.second);
}
//关键每次执行的任务是最多的那一个。
int time = 0;
int cur = 0;
int sz = t.size();
while(t[cur])
{
if(t[cur])
t[cur]--;
time++;
int gap = n;
int i = cur + 1;
int tmp = i;
while(gap > 0)
{
while(i < sz && t[i] == 0)
i++;
if(i < sz)
{
t[i++]--;
}
else
{
if(t[cur] == 0)
break;
}
time++;
gap--;
}
stable_sort(t.begin(),t.end(),greater());
}
return time;
}
};