1、Q136只出现一次的数据
我的思路:哈希,一个bool数组,初始为假,和一个和的值sum,第一次访问到次元素时,数组改为真,sum加上此数,第二次访问到时,sum减去次数,如此一来,出现两次的数便被抵消掉。最终sum就是要返回的值。代码如下:
int singleNumber(vector<int>& nums) {
//采用哈希,不满足空间复杂度要求,先试试
int n = nums.size();
long long sum = 0;
bool zai[60001] = {false};
for(int i = 0; i < n; i++){
if(zai[nums[i] + 30000] == false){//第一次遇到
zai[nums[i]+30000] = true;
sum += nums[i];
}else sum -= nums[i];//第二次遇到,抵消掉
}
return sum;
}
但是题目要求,要用常量额外空间,我这样开辟了数组显然不符合要求。
题解:用的是异或,相同位为0,不同位异或为1,异或有交换律定理,相当于将相同的数字先异或,这样两两异或就只剩0了,然后0再和最后的一个数字异或得到最终值
代码如下:
int singleNumber(vector<int>& nums) {
int ans = nums[0];
if (nums.size() > 1) {
for (int i = 1; i < nums.size(); i++) {
ans = ans ^ nums[i];
}
}
return ans;
}
这个思路确实很厉害。但是很奇怪,最后无论是时间还是空间,都没有哈希快
2、Q144二叉树前序遍历
采用颜色标记法,参考之前写过的中序遍历代码,只用改变入栈顺序即可,代码如下:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
stack<pair<TreeNode*, int> > stk;
stk.push((make_pair(root, 0)));
while(! stk.empty()){
auto [node, type] = stk.top();
stk.pop();
if(node == nullptr) continue;
if(type == 0){//当前结点为白色
//先序遍历入栈顺序应该是右、左、根
stk.push(make_pair(node->right, 0));
stk.push(make_pair(node->left, 0));
stk.push(make_pair(node, 1));//根标记为黑色
}else ans.emplace_back(node->val);//已经访问过的就加入答案里
}
return ans;
}
3、Q145二叉树的后序遍历
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans;
stack<pair<TreeNode*, int> > stk;
stk.push(make_pair(root, 0));
while(! stk.empty()){
auto [node, type] = stk.top();
stk.pop();
if(node == nullptr) continue;//结点为空的判断不要忘了
if(type == 0){//当前节点为白色
//后续遍历按照根、右、左的顺序入栈
stk.push(make_pair(node, 1));
stk.push(make_pair(node->right, 0));
stk.push(make_pair(node->left, 0));
}else ans.emplace_back(node->val);
}
return ans;
}