- 20220517再来一篇,现在leetcode周赛还处于1.5题水平
- 20220531 剑指刷完一次,事实上,身体状态不好的时候,一天做12个题目真的累。
接下来开始巩固和复习,查漏补缺!!!
132、bug
while(flag){
if(flag) ++count;
flag << 1;
}
上面这段代码报错: signed integer overflow: 2147483647 + 1 cannot be > represented in type ‘int’
因为flag一直没有更新,导致陷入了死循环,所以count会溢出;另外signed integer就是指的int
改成下面这样就好了:
while(flag){
if(flag & n) ++count;
flag = flag << 1;
}
133、求绝对值
abs()对整型变量求绝对值
fabs()对浮点型变量求绝对值。
134、细节
return absN % 2 == 0? ans : ans * x;
return absN / 2 == 0? ans * ans : ans * ans * x;//这样的话在absN=1的时候就会出错
135、位运算优化
- 判断奇数和偶数
传统方法
int n;
n % 2 == 0;
为0是偶数
为1是奇数
位的方法
n & 1 = 0; 偶数
n & 1 = 1; 奇数
- 除2运算
n >> 1;
等效于n / 2;
总结,下面这俩是一样的
if((n & 1) == 0)
if(n % 2 == 0)
136、字符操作
- 如果我们用一个char与一个int相加,我们会得到一个char。比如:
'0' + 1 = 48 + 1 = 49 = '1';
- 如果我们用一个char减去另一个char,我们会得到一个int。比如:
'2' - '0' = 50 - 48 = 2;
- 如果我们想把一个int型的数(比如 i = 5)转成char型,我们可以写成:
char c = i + '0';
- 如果我们想把一个char型的数(比如 c = ‘5’)转成int型,我们可以写成:
int i = c - '0';
137、求子串
string han = "_wo ai ni!";
cout << han.substr(1) << endl;//从1开始到节为的字符串,sh"wo ai ni!"
cout << han.substr(1,2) << endl;//从1开始的2位字符串,输出 “wo”
cout << han.substr(10) << endl;//输出空白字符串
138、枚举类型
enum State {
STATE_INITIAL,
STATE_INT_SIGN,
STATE_INTEGER,
STATE_POINT,
STATE_POINT_WITHOUT_INT,
};
139、写代码的错误
int pos = 5;
while(pos > 0){
right = right->next;
pos--; //忘了这一句话的,日,用cout调试了很久 才行的
}
140、虚拟节点的写法
ListNode* head = nullptr;//不能这样写,因为这样head->next就不存在了
ListNode* head = new ListNode(0);//注意这个new
TreeNode* tmp;//这样写也是可以的
141、提交代码的时候最好删除自己的测试语句
142、变量位置的不同(找bug游戏)
bool a = false;
bool b = true;
//这种写法会报错,因为变量c的生命周期只在if内
//if (1) bool c = a || b;
//cout << c;
bool c;
if (1) c = a || b;//另外,不能写成a|b,这是位操作 与
cout << c;
143、行和列
- row 行
- column 列
145、bug_____stack.top()
报错:reference binding to misaligned address 0xbebebebebebec0ba for type> ‘int’,
stack.top()访问了空的容器。
stack<int> st;
if(st.top() == pop){ ... }//这样会出错,st为空时,采用st.top()函数会报错的
if(!st.empty() && st.top() == pop){ ... }//改成这样就行了
146、多考虑边界条件
多考虑如 root为空的情况
147、首尾都能查看和删除的结构,双端数组deque
front() 返回第一个元素的引用,back() 返回最后一个元素的引用。
push_back() 在序列的尾部添加一个元素,push_front() 在序列的头部添加一个元素。
pop_back() 移除容器尾部的元素, pop_front() 移除容器头部的元素。
148、用迭代器赋值
vector<char> vec{'a', 'b'};
string s(vec.begin(), vec.end());
cout<<vec[1]<<endl;//输出b
cout<<s[1]<<endl;//输出b
vector<int> vec2{1, 2, 3, 4, 5};
vector<int> vec3(vec2.begin(), vec2.end());
cout<<vec3[1];//输出2
vector<vector<int>> ans;
deque<int> path;
ans.emplace_back(vector<int>(path.begin(), path.end()));
149、vector为空判断
vector<int> postorder)
if(!postorder) return true;//postorder不是一个指针,所以这样写是不行的
if(postorder.empty()) return true;//这样是对的
150、bug报错
member access within null pointer of type ‘TreeNode’ (solution.cpp)
通常是TreeNode的空对象的成员访问。前面加一个为空处理就行了。
path.emplace_back(root->val);
改成下面这样
if(!root) return ans;
path.emplace_back(root->val);
151、返回值为void的函数
- 可以没有return
- 也可以直接
return;
152、回溯全排列去重
unordered_set<string> ans;
vector<string> ansFinal(ans.begin(), ans.end());
return ansFinal;
153、随机数rand()
int n = rand() % 12;
产生一个0-11的随机数
154、bug
error: expected ‘;’ after expression
vecto ans(arr.begin(), arr.begin() + k);
vector<int> ans(arr.begin(), arr.begin() + k);//写成了vecro
155、尽量看清楚题目
- 那么中位数就是位于中间的数值
- 那么中位数就是所有数值排序之后位于中间的数值
这两句话一开就没有看到区别
156、大小堆(优先队列)
大顶堆
priority_queue<int> p;//默认是大顶堆,
等效于priority_queue<int,vector<int>, less<int>> p;
小顶堆,p.top()是最小值
priority_queue<int,vector<int>, less<int>> p;
157、失误
- szie 应该是size,这个有毒,老是写错。
158、写题目技巧
遇到边界问题,只需要举一个例子就好了,和以前一样,和李永乐的线性代数一样。
159、语法细节
long long a;
max(a, 10);报错,因为10默认为int
max(a, 10LL)可以采用强制类型转换即可,
160、自定义sort排序规则
痛苦的1小时,20220528,这个题目好多细节啊,看来有必要短期内再过一遍基础了。
- 自定义排序方法1:
class Solution {
public:
static bool cmd(int a, int b){//前面要加上这个static
string ab = to_string(a) + to_string(b);
string ba = to_string(b) + to_string(a);
if(ab < ba) return true;
else return false;//妈的。这里写成了 else false;忘记return
}
string minNumber(vector<int>& nums) {
string ans;
sort(nums.begin(), nums.end(), cmd);
for(auto n : nums){
ans += to_string(n);
}
// string ans(nums.begin(), nums.end());//因为nums内是数字,string内部是char,所以不能复制,改成下面这样就行了
return ans;
}
};
- 自定义排序2
sort(nums.begin(), nums.end(),
[](int a, int b){
string ab = to_string(a) + to_string(b);
string ba = to_string(b) + to_string(a);
if(ab < ba) return true;
else return false;});
- 自定义排序3
priority_queue<int, vector<int>, greater<int>> minHeap;变成最小堆,默认是最大堆
容器复制的一些细节
//vector<int> nums = { 1, 2, 5, 6};//这样不行
vector<char> nums = { '1', '2', '3', '6'};//行了
string s(nums.begin(), nums.end());
cout<<s;
161、多重选择的语句的区别
if(dp[i] == num2) ++p2;
else if(dp[i] == num3) ++p3;
else if(dp[i] == num5)++p5;
else continue;
if(dp[i] == num2) ++p2;
if(dp[i] == num3) ++p3;
if(dp[i] == num5) ++p5;
它俩的区别。当num2 == num3时,执行的逻辑就不同了,上面的只有++p2,下面的执行++p2和++p3。
163、缩写
缩写 | 全名 |
---|---|
cnt | count |
ret | return |
ans | answer |
164、排好序的数组
- 多数用二分查找
165、位运算
对这类题目很不熟悉
vector<int>& nums)
int index = 0;
for(int n : nums) index = index ^ n;
nums中的相同元素都没了,因为5^5 = 0;
if((div & n) == 1) //这样不行 ,前面是二进制,后面是十进制
if((div & n) == 0)//这样可以
if((div & n) )//这样也可以
166、对组的使用
- 这是pair在优先队列中的使用priority_queue
priority_queue<pair<int, int>> pq;
pq.emplace(make_pair(1, 2));//可以
pq.emplace(1, 2);//这样也行
pq.insert(1, 2);//这样不行,不用make_pair是emplace的功能
- 注意对比它和map的用法区别,priority_queue中是一个元素,而在map中是两个。
map<int, int> ma;
ma.insert(make_pair(1, 2));
//ma.insert((1, 2));//这样不行的
cout << ma[1];
167、单调队列
就是个deque(叫做双端队列或者双端数组),但是使用的过程中自己保证deque内的元素是单调的。(leetcode239题)
push_back() 在序列的尾部添加一个元素。
push_front() 在序列的头部添加一个元素。
pop_back() 移除容器尾部的元素。
pop_front() 移除容器头部的元素。
168、vector对象赋值
vector<int> a(5, 1);
vector<int> b(10, 1);
a = b;这样操作下来a={1,1,1,1,1,1,1,1,1,1};
169、进制代称
D(decimal)表示这个数是十进制
B(binary)表示这个数是二进制
O(octor)表示这个数是八进制
H(hex)表示这个数是十六进制
170、 if 的一种等效写法
a && b;
和下面这个等效,利用了&&的短路效应。
if(a == 0) b;
171、继续强化的部分
- 位运算
- 字符串处理时候的自动机(状态机)
- 并查集