Day1
704 二分查找,简单
我也有自己写题解的能力了,而且思维很清晰:
找什么就在if里写什么。
-
class Solution {
-
public:
-
int search(vector<int>& nums, int target) {
-
int l=0,r=nums.size()-1;
-
while(l<r){
-
int mid=l+r>>1;
-
if(nums[mid]<target){
-
l=mid+1;
-
}
-
else{
-
r=mid;
-
}
-
}
-
if(nums[l]==target) return l;
-
return -1;
-
}
-
};
-
class Solution {
-
public:
-
int search(vector<int>& nums, int target) {
-
int l=0,r=nums.size()-1;
-
while(l<r){
-
int mid=(l+r+1)>>1;
-
if(nums[mid]>target){
-
r=mid-1;
-
}
-
else{
-
l=mid;
-
}
-
}
-
if(nums[l]==target) return l;
-
return -1;
-
}
-
};
35 搜索插入的位置,简单
自己想的:找右边界,代码比之前的简洁很多:
- class Solution {
- public:
- int searchInsert(vector<int>& nums, int target) {
- int l=0,r=nums.size()-1;
- while(l<r){
- int mid=(l+r+1)>>1;
- if(nums[mid]>target) r=mid-1;
- else l=mid;
- }
- if(nums[l]<target) return l+1;
- return l;
- }
- };
34 排序数组中查找元素的第一个和最后一个位置,中等
哇神呀,自己写的:
Line 1037: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h)是空指针访问,注意检查nums.size()==0
- class Solution {
- private:
- int get_left(vector<int>&nums,int target){
- int l=0,r=nums.size()-1;
- while(l<r){
- int mid=l+r>>1;
- if(nums[mid]<target) l=mid+1;
- else r=mid;
- }
- if(nums[l]==target) return l;
- return -1;
- }
- int get_right(vector<int>&nums,int target){
- int l=0,r=nums.size()-1;
- while(l<r){
- int mid=(l+r+1)>>1;
- if(nums[mid]>target) r=mid-1;
- else l=mid;
- }
- if(nums[l]==target) return l;
- return -1;
- }
- public:
- vector<int> searchRange(vector<int>& nums, int target) {
- if(nums.size()==0) return {-1,-1};
- int low=get_left(nums,target);
- int high=get_right(nums,target);
- return {low,high};
- }
- };
27 移除元素,简单
快慢双指针入门。
- class Solution {
- public:
- int removeElement(vector<int>& nums, int val) {
- // i slow
- // j fast
- int i=0;
- for(int j=0;j<nums.size();j++){
- while(j<nums.size()&&nums[j]!=val)
- nums[i++]=nums[j++];
- while(j<nums.size()&&nums[j]!=val)
- j++;
- }
- return i;
- }
- };
其实第二句while写错了,但是竟然通过了。说明第二句while根本就没有执行!
性能很差,让我们优化一下:
直接删除第二句while就好了!因为nums[j]==val的话 根本不会进入while,交给for里面的j++来处理就好了:
- class Solution {
- public:
- int removeElement(vector<int>& nums, int val) {
- // i slow
- // j fast
- int i=0;
- for(int j=0;j<nums.size();j++){
- while(j<nums.size()&&nums[j]!=val)
- nums[i++]=nums[j++];
- }
- return i;
- }
- };
DAY2
977 有序数组的平方,简单
- class Solution {
- public:
- vector<int> sortedSquares(vector<int>& nums) {
- for(auto &n:nums) n*=n;
- sort(nums.begin(),nums.end());
- return nums;
- }
- };
没什么好说的。
209 长度最小的子数组,中等
最短连续子数组问题,滑动窗口。
怎么就一直学不会滑动窗口呢。。。
没做出来,发现问题了,滑动的应当是右指针for()里面填,这样一来,sum的初始化应当放到for的外面。Res的更新语句放的位置也有问题。我刚开始想错了,应当是:
//最短,一发现符合,就缩
//如果是最长,一发现不符合,就扩
很有收获。
- class Solution {
- public:
- int minSubArrayLen(int target, vector<int>& nums) {
- int bestres = INT_MAX, l = 0, tmpres = 0;
- int sum=0;
- for (int r = 0; r < nums.size(); r++) {
- sum += nums[r];
- // 最短,一发现符合,就缩
- // 如果是最长,一发现不符合,就扩
- while (sum >= target) {
- tmpres = r - l + 1;
- bestres = min(tmpres, bestres);
- sum -= nums[l++];
- }
- }
- if(bestres==INT_MAX) return 0;
- return bestres;
- }
- };
59 螺旋矩阵 II ,中等
不行呀,还是卡住了。
忘记更新x,y了。并且:走过了 !=0 那么就要更新偏移量。
- class Solution {
- public:
- vector<vector<int>> generateMatrix(int n) {
- vector<vector<int>> res(n,vector<int>(n,0));
- int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
- for(int x=0,y=0,d=0,k=1;k<=n*n;k++){
- //走过了或者撞墙
- res[x][y]=k;
- int a=x+dx[d],b=y+dy[d];
- if(a<0||a>n-1||b<0||b>n-1||res[a][b]!=0){
- d=(d+1)%4;
- a=x+dx[d];
- b=y+dy[d];
- }
- //更新x,y!!
- x=a,y=b;
- }
- return res;
- }
- };
DAY3
203移除链表元素,简单
Runtime error;因为缺少了一个更新当前指针的语句
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode() : val(0), next(nullptr) {}
- * ListNode(int x) : val(x), next(nullptr) {}
- * ListNode(int x, ListNode *next) : val(x), next(next) {}
- * };
- */
- class Solution {
- public:
- ListNode* removeElements(ListNode* head, int val) {
- if(head==nullptr) return head;
- ListNode* dummyhead=new ListNode(0);
- dummyhead->next=head;
- ListNode* p=dummyhead;
- //缺少一个更新指针的语句!
- while(p->next!=nullptr){
- if(p->next->val==val) p->next=p->next->next;
- else p=p->next;
- }
- return dummyhead->next;
- }
- };
ACWING29 删除链表中重复的节点
因为是排序的链表,那么只用针对连续情况去做判断和处理。
只要指针右移了,而且要访问其val或者next,则使用前必须判空(判自己,而不是next),否则会造成段错误。
题面:在一个排序的链表中,存在重复的节点,请删除该链表中重复的节点,重复的节点不保留。
这题有难度,要求重复的节点不保留,显然需要三指针了。
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
- class Solution {
- public:
- ListNode* deleteDuplication(ListNode* head) {
- if(head==nullptr) return head;
- auto dummy= new ListNode(-1);
- dummy->next=head;
- auto p=dummy;
- auto t=head;
- auto q=head->next;
- while(q!=nullptr){
- while(q!=nullptr&&q->val!=t->val){
- p=t;
- t=q;
- q=q->next;
- }
- if(q==nullptr) break;
- while(q!=nullptr&&q->val==t->val){
- q=q->next;
- }
- p->next=q;
- t=q;
- if(q!=nullptr)q=q->next;
- }
- return dummy->next;
- }
- };
206反转链表,简单
迭代法和递归法都思路不清晰或者说没思路!重新学咯:
迭代法和递归法。
迭代法:
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode() : val(0), next(nullptr) {}
- * ListNode(int x) : val(x), next(nullptr) {}
- * ListNode(int x, ListNode *next) : val(x), next(next) {}
- * };
- */
- class Solution {
- public:
- ListNode* reverseList(ListNode* head) {
- if(head==nullptr) return head;
- //这句初始化很重要,我们要让反转后的最后一个元素指向nullptr,那么head的pre自然应该初始化为nullptr
- ListNode* pre=nullptr;
- ListNode* cur=head;
- //条件也重要呀,不用判它的next,手写模拟就知道了。
- while(cur!=nullptr){
- ListNode* tmp=cur->next;
- cur->next=pre;
- pre=cur;
- cur=tmp;
- }
- //return 的是什么?好好想想 当然是pre
- return pre;
- }
- };
递归法:想不出来呀。
太抽象了,不管了。