易错点总结
易错点
剑指 Offer 18. 删除链表的节点
必须要new一个dummy,而不是直接创建一个ListNode*,具体原因:
剑指 Offer 28. 对称的二叉树
非常规的解法。这种思路只能通过60%的用例:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == NULL || (root->left==NULL && root->right==NULL))return true;
if(root->left==NULL || root->right==NULL) return false;
if(root->left->val != root->right->val) return false;
return isSymmetric(root->left) && isSymmetric(root->right);
}
};
只需要加一句话:
swap(root->left->right, root->right->right);
就是在每次判断完之后,交换左子树的右和右子树的右,以上思路只能判断是不是想等的,而不是对称,若对称,交换后就是相等的。
剑指 Offer 29. 顺时针打印矩阵
思路倒是不难,主要是边界条件要处理好:不写这句话就是错误……
if (matrix.size() == 0 || matrix[0].size() == 0) {
return {};
}
剑指 Offer 30. 包含min函数的栈
错在哪儿了呢,就是mins.size()==0,为了图省事直接写了mins.top()明显是不对的
void push(int x) {
res.push(x);
if(mins.size()!=0 && mins.top() < x){
mins.push(mins.top());
}else {
mins.push(x);
}
}
剑指 Offer 32 - II. 从上到下打印二叉树 II
一看用层次遍历就比较方便,BFS,但是还是写错了,需要注意的是q.size()需要先保存,因为如果你直接放在for循环内,q会因为push而增加长度……
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
vector<vector<int>> ans;
if(root == NULL){
return ans;
}else{
q.push(root);
}
while(!q.empty()){
vector<int> res;
//不能直接放在for循环
int size = q.size();
for(int i = 0; i < size; i++){
TreeNode *t = q.front();q.pop();
res.push_back(t->val);
//push的是q队列
if(t->left)q.push(t->left);
if(t->right)q.push(t->right);
}
ans.push_back(res);
}
return ans;
}
};
剑指 Offer 40. 最小的k个数
小根堆,只输出前n个即可:
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if(arr.size() == 0 || k > arr.size())return {};
vector<int> res;
priority_queue<int, vector<int>, less<int>> q;
for(int c:arr){
if(q.size() <= k){
q.push(c);
}
else{
if(q.top() > c){
q.pop();
q.push(c);
}
}
}
for(int i = 0; i < q.size(); i++){
res.push_back(q.top());
q.pop();
}
return res;
}
};
剑指 Offer 42. 连续子数组的最大和
简单的动态规划,比较神奇的是:
这样对于[1],输出0,是错的
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size()-1;
if(n == 0) return 0;
if(n == 1) return nums[0];
int *dp = new int[n+1];
dp[0] = nums[0];
int m = dp[0];
for(int i = 1; i <= n; i++){
dp[i] = max (dp[i-1] + nums[i] , nums[i]);
m = max(m , dp[i]);
}
return m;
}
};
修改一下:nums.size()不减1立刻就成功了……原来是自己设置的判断条件……
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
if(n == 1) return nums[0];
int *dp = new int[n+1];
dp[0] = nums[0];
int m = dp[0];
for(int i = 1; i < n; i++){
dp[i] = max (dp[i-1] + nums[i] , nums[i]);
m = max(m , dp[i]);
}
return m;
}
};
剑指 Offer 50. 第一个只出现一次的字符
注意返回空char就是:’ ’
返回空字符串就是“ ”
class Solution {
public:
char firstUniqChar(string s) {
if(s.length() == 0) return ' ';
unordered_map<char, int> map;
for(int i = 0 ; i < s.length(); i++){
map[s[i]]++;
}
for(auto c:s){
if(map[c] == 1)return c;
}
return ' ';
}
};
剑指 Offer 52. 两个链表的第一个公共节点
是p1==NULL吗而不是p1->next
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p1 = headA, *p2 = headB;
while(p1 != p2){
//注意
p1 = p1 == NULL ? headB : p1->next ;
p2 = p2 == NULL ? headA : p2->next ;
}
return p1;
}
};
剑指 Offer 53 - II. 0~n-1中缺失的数字
“排序数组中的搜索问题,首先想到 二分法 解决。”
比较容易想到就是下标和内容不一样,但是还有更简单的做法,可以用类似于二分查找的做法:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int l = 0, r = nums.size();
while(l < r){
int mid = l + (r - l)/2;
if(nums[mid] > mid) r = mid;
if(nums[mid] == mid)l = mid + 1;
}
return l;
}
};
剑指 Offer 54. 二叉搜索树的第k大节点
怎么说呢,还是对自己有自信吧,二叉搜索树的中序遍历是顺序排序的,本来觉得不是这么做,一看解析就是这个方法……
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;int ans;
int kthLargest(TreeNode* root, int k) {
if(root == NULL)return 0;
dfs(root);
reverse(res.begin(), res.end());
for(int i = 0; i < k; i++){
ans = res[i];
}
return ans;
}
void dfs(TreeNode* root){
if(!root) return;
if(root){
dfs(root->left);
res.push_back(root->val);
dfs(root->right);
}
}
};
这种方法比较笨,聪明的是在遍历的时候就计数,k–了就直接return:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;int ks = 0, ans;
int kthLargest(TreeNode* root, int k) {
if(root == NULL)return 0;
ks = k;
dfs(root);
return ans;
}
void dfs(TreeNode* root){
if(!root) return;
if(root){
dfs(root->right);
ks--;
if(ks == 0){
ans = root->val;
return;
}
dfs(root->left);
}
}
};
剑指 Offer 55 - II. 平衡二叉树
先计算出左右子树高度,再看看是不是大于1,最后自己递归:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(!root)return true;
if ( abs(dfs(root->left) - dfs(root->right)) > 1 ) return false;
return isBalanced(root->left) && isBalanced(root->right);
}
int dfs(TreeNode* root){
if(!root) return 0;
return max(dfs(root->left), dfs(root->right))+1;
}
};