5月11日 50 Pow(x, n)
1.就是一个一个乘,暴力
2.分治,也就是相当于动规?
3.快速幂模板
3.大佬的思路 利用指数函exp和对数函数ln来巧妙转换。(很快)
(指数换为对数很重要的思路)
3
class Solution {
public:
double myPow(double x, int n) {
if(x==0)
return 0;
if(x>0||(x<0&&n%2==0))//答案是正数
return exp(n*log(abs(x)));
else
return -exp(n*log(abs(x)));
}
};
5月12日 155 最小栈
md,题一开始都没读明白
1.用一个数据栈,一个最大栈实现,最大栈保证最大值始终在最上面
2.把1中的两个栈合成一个栈(存两个数据)
2
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
if(w.empty())
w.push({x,x});
else
w.push({x,min(w.top().second,x)});
}
void pop() {
w.pop();
}
int top() {
return w.top().first;
}
int getMin() {
return w.top().second;
}
stack<pair<int, int>> w;
};
5月12日 102 二叉树的层序遍历
抄的,我连题都没看懂
5月13日 136 只出现一次的数字
就是个异或,直接秒,但是,为啥被这么多人击败????
class Solution {
public:
int singleNumber(vector<int>& nums) {
int sum = nums[0];
for (int i = 1; i < nums.size(); i++) {
sum ^= nums[i];
}
return sum;
}
};
这样快了不少
class Solution {
public:
int singleNumber(vector<int>& nums) {
int sum=0;
for (int i = 0; i < nums.size(); i++) {
sum ^= nums[i];
}
return sum;
}
};
5月14日 560 和为K的子数组
无语
明明很简单的一道题,细节问题就是处理不好,感觉做题的状态也不好,人都是恍惚的
c++也不熟悉,哎~
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int sum=0;
int anda=0;
unordered_map<int ,int>ans;
ans[0]=1;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
if(ans.find(sum-k)!=ans.end())
anda+=ans[sum-k];
ans[sum]++;
}
return anda;
}
};
5月15日 25 K 个一组翻转链表
不会,没有写
5月16日 136 只出现一次的数字
????为啥出现两次
老话说的好:位运算大法好,直接异或就过了
class Solution {
public:
int singleNumber(vector<int>& nums) {
int res = 0;
for (int i = 0; i < nums.size(); i++) {
res ^= nums[i];
}
return res;
}
};
5月17日 210 课程表 II
复习一下kahn算法,模板题?
看起来比较长,是因为变量名太长了
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<int>q[numCourses];
int xu[numCourses];
memset(xu,0,sizeof(xu));//要初始化,我觉得是因为这个不是全局变量
vector<int>ans;
queue<int>w;
for(int i=0;i<prerequisites.size();i++){
xu[prerequisites[i][0]]++;//入度,注意是什么入度
q[prerequisites[i][1]].push_back(prerequisites[i][0]);
}
for(int i=0;i<numCourses;i++){
if(xu[i]==0)
w.push(i);
}
while(!w.empty()){
int k=w.front();
w.pop();
ans.push_back(k);
for(int i=0;i<q[k].size();i++){
xu[q[k][i]]--;
if(xu[q[k][i]]==0)
w.push(q[k][i]);
}
}
if(ans.size()!=numCourses)
ans.clear();//记得当不能够完成所有题目时,返回空
return ans;
}
};
5月18日 152 乘积最大子数组 (不是很懂)
没会哈哈哈,看的题解
代码简单,就是不会
class Solution {
public:
int maxProduct(vector<int>& nums) {
int maxmax=1,minmin=1,max1=-999999999;
for(int i=0;i<nums.size();i++){
if(nums[i]<0)//交换最大最小值
{
int p=maxmax;
maxmax=minmin;
minmin=p;
}
maxmax=max(nums[i]*maxmax,nums[i]);
minmin=min(nums[i]*minmin,nums[i]);
max1=max(maxmax,max1);
}
return max1;
}
};
5月19日 680 验证回文字符串 Ⅱ
题中只让删除一个,两个下标从最左,最右开始出发,遇到不相等时
两种删除方法(删左下标或者右下标的),对删除后中间的字串判断是不是回文就好了(字符串翻转reverse一下就好了)
思路还是清晰
class Solution {
public:
bool validPalindrome(string s) {
int i=0;
int j=s.size()-1;
while(i<=j){
if(s[i]!=s[j]){
string k=s.substr(i,j-i);
string k1=k;
reverse(k.begin(),k.end());
string p=s.substr(i+1,j-i);
string p1=p;
reverse(p.begin(),p.end());
if(k1==k||p1==p)
return true;
else
return false;
}
i++;
j--;
}
return true;
}
};
5月20日 1371 每个元音包含偶数次的最长子字符串
很好的一道题,但是我不会
毕竟我连状态压缩是啥都不晓得
涉及了状态压缩,前缀和,位运算,哈希表
状态压缩就是。。。你懂的!用二进制表示最常见
哈希表就是让如果出现两种相同的状态,就说明两个里面满足题意
class Solution {
public:
int findTheLongestSubstring(string s) {
int p = 0,maxmax=0;
vector<int>ans(32, -1);//一共有32种状态,-1时表示还没有出现过这种状态
ans[0] = 0;//因为aeiou都没有吗,也是全部出现偶数次
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'a') {
p ^= 1 << 0;//左移运算符
}
else if (s[i] =='e' ) {
p ^= 1 << 1;
}
else if (s[i] =='i' ) {
p ^= 1 << 2;
}
else if (s[i] =='o' ) {
p ^= 1 << 3;
}
else if (s[i] == 'u') {
p ^= 1 << 4;
}
if (ans[p] != -1) {//说明以前出现过该状态
maxmax = max(i - ans[p] + 1, maxmax);
}
else {
ans[p] = i+1;
}
}
return maxmax;
}
};
这么久没更是因为太难了,不会,呜呜呜
5月27日 974 和可被 K 整除的子数组
求一个连续段被k整除
前缀和处理后就是c[i]%k-c[j]%k=s%k=0,就是找前缀中余数相等的
明明做过,就是不会
class Solution {
public:
int subarraysDivByK(vector<int>& A, int K) {
int ans=0;
int c[K+1],sum[A.size()+1];
memset(sum,0,sizeof(sum));
memset(c,0,sizeof(c));//两个记得初始化
c[0]++;//前缀处理时,记得0
sum[0]=0;
for(int i=1;i<=A.size();i++){
sum[i]=sum[i-1]+A[i-1];//前缀和处理
c[(sum[i]%K+K)%K]++;//注意负数取余
}
for(int i=0;i<K;i++){
ans+=c[i]*(c[i]-1)/2;
}
return ans;
}
};
5月28日 394 字符串解码
哈啊哈,第一个自己写的双百,可喜可贺
本质就是一个栈模拟,注意一下细节就好了
用 ‘ ] ’ 作为处理的标识符
代码里有详细解释
class Solution {
public:
string decodeString(string s) {
stack<char>c;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ']') {
string ss;
while((c.top()>='a'&&c.top()<='z')||(c.top()>='A'&&c.top()<='Z')){
//tmd,居然还有大写字母,注意审题
ss += c.top();
c.pop();
}
c.pop();//删除‘[’
int k=0;
int t=1;
while(!c.empty()&&(c.top()>='0'&&c.top()<='9')){
//循环是为了找到前面的数,数不一定是小于10的数,WA了一次在这里
int p=c.top()-'0';
k=p*t+k;
t*=10;
c.pop();
}
while (k--)
for (int j = ss.size() - 1; j >= 0; j--) //放进栈里
c.push(ss[j]);
}
else c.push(s[i]);//如果没有处理标志‘]’,就直接放入栈里
}
string ans;
while (!c.empty()) {
ans += c.top();
c.pop();
}
reverse(ans.begin(), ans.end());//记得反向
return ans;
}
};
5月29日 198 打家劫舍
说的是简单题,也反应过是DP,可还是卡到我了,难受!
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
int k = nums.size();
vector<int>ans=vector<int>(k, 0);//初始化方法,记住了!!!
if (k == 1)
return nums[0];
ans[0] = nums[0];
ans[1] = max(nums[0], nums[1]);
//ans记录从下标0-n的最大值
for (int i = 2;i<k; i++) {
ans[i] = max(ans[i - 2] + nums[i], ans[i - 1]);
}
return ans[nums.size() - 1];
}
};
5月30日 84 柱状图中最大的矩形
给的是困难
但也没有那么困难
但我也不会,抄的
5月31日 101 对称二叉树
简单还是简单,但我是抄的
class Solution {
public:
bool check(TreeNode *p, TreeNode *q) {
if (!p && !q) return true;//p,q都为空
if (!p || !q) return false;//p,q为空情况不同
return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
6月1日 1431 拥有最多糖果的孩子
简单题,直接些就好了,注意vector赋值的时候用pushback,用【】力扣不给过
public:
vector<bool> kidsWithCandies(vector<int>& candies, int extraCandies) {
int maxmax = -1;
int k = candies.size();
for (int i = 0; i < k; i++) {
maxmax = max(maxmax, candies[i]);
}
vector<bool>c;
for (int i = 0; i < k; i++) {
if (candies[i] + extraCandies >= maxmax)
c.push_back(true);
else
c.push_back(false);
}
return c;
}
};
6月2日 64 求1+2+…+n
确实没想到最好的那一种解法
只想到了一种pow和<<的解法,实际上pow也是乘法实现
class Solution {
public:
int sumNums(int n) {
return ((int)pow(n,2)+n)>>1;
}
};
最优解法 是一种 短路 思想
因为没法乘,所以只能加,怎样弄出循环很关键
&& 和 || 就有这样的功能,前者前项为否就不会执行后项,后者前项为真就不会执行后项
class Solution {
public:
int sumNums(int n) {
n && (n += sumNums(n - 1));
return n;
}
};
6月3日 837 新21点
写不来
6月4日 238 除自身以外数组的乘积
要求不能用除法,还是很简单的
双向前缀处理一下就好了
复杂度 o(n)
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
vector<int>qian(nums.size()+1,0);
vector<int>hou(nums.size()+1,0);
int sum=1;
qian[0]=1;
for(int i=0;i<nums.size();i++){
sum*=nums[i];
qian[i+1]=sum;
}
sum=1;
hou[nums.size()]=1;
for(int i=nums.size()-1;i>=0;i--){
sum*=nums[i];
hou[i]=sum;
}
vector<int>ans(nums.size(),0);
for(int i=0;i<nums.size();i++){
ans[i]=qian[i]*hou[i+1];
}
return ans;
}
};
自己写的有点长,可以一次循环就好
class Solution
{
public:
vector<int> productExceptSelf(vector<int>& nums)
{
int n = nums.size();
//把向量output初始化为1
vector<int> output(n,1);
//采用两端同时累乘,最终得到的ouput[i]的值即除nums[i]以外的乘积
int left = 1,right = 1;
for(int i = 0; i < n; i++)
{
//0~i-1项乘积置于output[i]
output[i] *= left;
left *= nums[i];
//output[i]再乘以i+1~n-1项
output[n-1-i] *= right;
right *= nums[n-1-i];
}
return output;
}
};
6月5日 面试题29 顺时针打印矩阵
比较简单的模拟题
但是容易绕
我代码写的有点繁琐了,上的别人的代码
坑点:特判数组为空时
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector <int> res;
if(matrix.empty()) return res;
int rl = 0, rh = matrix.size()-1; //记录待打印的矩阵上下边缘
int cl = 0, ch = matrix[0].size()-1; //记录待打印的矩阵左右边缘
while(1){
for(int i=cl; i<=ch; i++) res.push_back(matrix[rl][i]);//从左往右
if(++rl > rh) break; //若超出边界,退出
for(int i=rl; i<=rh; i++) res.push_back(matrix[i][ch]);//从上往下
if(--ch < cl) break;
for(int i=ch; i>=cl; i--) res.push_back(matrix[rh][i]);//从右往左
if(--rh < rl) break;
for(int i=rh; i>=rl; i--) res.push_back(matrix[i][cl]);//从下往上
if(++cl > ch) break;
}
return res;
}
};
6月6日 128 最长连续序列
就是查,有点小技巧
从”最小“的地方开始查
unordered_set比vector快好多好多
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> set;//set好快
for (int i = 0; i < nums.size(); i ++) set.insert(nums[i]); //去重
int mmax = 0;
for (int i = 0; i < nums.size(); i ++)
if (!set.count(nums[i] - 1)) { //未找到,也就是从最小的开始
int cnt = 0, num = nums[i];
while(set.count(num)) cnt ++, num ++; //找到了
mmax = max(mmax, cnt);
}
return mmax;
}
};
6月7日 126 单词接龙 II
给忘了,没有写
6月8日 990 等式方程的可满足性
并查集模板
先把所有==情况用并查集连接,再遍历所有!=判断是否冲突
(==情况之间肯定不会冲突)
就是其中一个细节注意一下
//并查集模板
//但还是有个细节要注意
class Solution {
public:
int chu[30];
int zu(int a) {
if (a != chu[a])
return chu[a] = zu(chu[a]);
return a;
}
void he(int a, int b) {
a = zu(a);
b = zu(b);
chu[a] = b;
}
bool equationsPossible(vector<string>& equations) {
for (int i = 0; i < 30; i++)chu[i] = i;
for (int i = 0; i < equations.size(); i++) {
if (equations[i][1] == '=') {
he(equations[i][0] - 'a', equations[i][3] - 'a');
}
}
for (int i = 0; i < equations.size(); i++){
if(equations[i][1] != '='){
if (zu(equations[i][0] - 'a') == zu(equations[i][3] - 'a'))
//注意细节,用zu查找,不要用chu直接比较
return false;
}
}
return true;
}
};
6月9日 面试题46 把数字翻译成字符串
前排恭喜:一遍过+双百
就是个DP
如过本次数位可以和前面的数构成10——25,
那么ans[i]=ans[i-1]+ans[i-2]
否则ans[i]=ans[i-1]
int ans[20];
class Solution {
public:
int translateNum(int num) {
string s = to_string(num);
if (s.size() == 1)
return 1;
ans[0] = 1;
ans[1] = 1;
for (int i = 2; i <= s.size(); i++) {//数字个数
int k=s[i-1] - '0' + 10 * (s[i - 2] - '0');//与前面的数组合
if (k >= 10 && k <= 25)
ans[i ] = ans[i-2]+ans[i - 1];
//两种选择,一种与前一位数结合形成一个数(ans[i-2]),
//另一个是不进行结合(ans[i-1])
else
ans[i ] = ans[i-1];
//只有一种选择
}
return ans[s.size()];
}
};
6月10日 9 回文数
zz模拟,毫无技巧
class Solution {
public:
bool isPalindrome(int x) {
string s = to_string(x);
string ss = s;
reverse(ss.begin(), ss.end());
if (ss == s)
return true;
else
return false;
}
};
6月11日 739 每日温度
很明显的单调栈
栈里储存序号
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
stack<int>c;//装序号
vector<int>ans(T.size());//一定记得初始化
for (unsigned int i = 0; i < T.size(); i++) {
while (!c.empty() && T[c.top()] < T[i]) {
ans[c.top()] = i - c.top();
c.pop();
}
c.push(i);
}
return ans;
}
};
6月12日 15 三数之和
我不会,代码是我抄的。
双指针考察
双指针重中之重:相当于每一个都穷举了
精华都在代码里
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end()); //排序
vector<vector<int>> res; //定义输出
for (int i = 0; i < nums.size() && nums[i] <= 0; i ++) { //如果当前数字大于0,则三数之和一定大于0,结束循环
if (i > 0 && nums[i] == nums[i - 1]) continue; //(i > 0)防止越界
int j = i + 1, k = nums.size() - 1;
while (j < k && nums[k] >= 0) { //如果nums[k] < 0,则三数之和一定小于0.结束循环
if (nums[j] + nums[k] == -nums[i]) {
res.push_back({nums[i], nums[j], nums[k]});
while (j < k && nums[j] == nums[j + 1]) j ++;
while (j < k && nums[k] == nums[k - 1]) k --;
j ++, k --;
}
else if (nums[j] + nums[k] < -nums[i]) j ++;
else k --;
}
}
return res;
}
};
//我是抄的,写的牛逼
6月13日 70 爬楼梯
双百通过
直接写就好了
class Solution {
public:
int climbStairs(int n) {
if(n==1)
return 1;
else if(n==2)
return 2;
else{
int p=1,q=2;
for(int i=3;i<=n;i++){
int k=q;
q=p+q;
p=k;
}
return q;
}
}
};
7月6日 63 不同路径 II
动态规划的模板题了,但是一开始没想到是动态规划
注意一开始起点[0][0]就是障碍的情况,特判一下
class Solution {
//一开始没想到动态规划
public:
long long ans[106][106];
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int a=obstacleGrid.size()-1;
int b=obstacleGrid[0].size()-1;
if(obstacleGrid[0][0]==1)
return 0;//特判
for(int i=0;i<=a;i++){
for(int j=0;j<=b;j++){
if(i==0&&j==0)
ans[i][j]=1;
else if(obstacleGrid[i][j]==1)
ans[i][j]=0;
else if(i==0)
ans[i][j]=ans[i][j-1];
else if(j==0)
ans[i][j]=ans[i-1][j];
else
ans[i][j]=ans[i-1][j]+ans[i][j-1];
}
}
return ans[a][b];
}
};
7月7日 112 路径总和
简单题,递归大法好!
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(root==NULL)
return false;//这个都是套路判断了
else if(root->left==NULL&&root->right==NULL)
return sum==root->val;
else return hasPathSum(root->right,sum-root->val)||hasPathSum(root->left,sum-root->val);
}
};
7月8日 面试题 16.11. 跳水板
注意处理一下细节就好了,简单题,直接写
class Solution {
public:
vector<int> divingBoard(int shorter, int longer, int k) {
if(k==0)
return {};//返回空vector
if(shorter==longer)
return {shorter*k};//防止出现长度相同的木棍
int s=shorter*k;
int h=longer-shorter;
vector<int>ans;
for(int i=0;i<=k;i++){//是k+1次,不是k次
ans.push_back(s);
s+=h;
}
return ans;
}
};
7月9日 面试题 17.13. 恢复空格
写不来
实话实说,才我是真的菜,知道用DP都能把我卡死
class Solution {
public:
int ans[1006];
int respace(vector<string>& dictionary, string sentence) {
ans[0] = 0;
for (int i = 1; i <= sentence.size(); i++) {
ans[i] = ans[i - 1]+1;//关键
for (int j = 0; j < dictionary.size(); j++) {
int k = dictionary[j].size();
if (i >= k&&sentence.substr(i-k,k)==dictionary[j])
ans[i] = min(ans[i], ans[i - k]);
}
}
return ans[sentence.size()];
}
};