DAY1 数组part01
今日任务
数组理论基础,704. 二分查找,27. 移除元素
数组理论基础
文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
*C++中,二维数组连续分布
704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
*二分适用:有序数组,数组中无重复元素
*重点注意边界条件
1 class Solution { 2 public: 3 int search(vector<int>& nums, int target) { 4 int i=0; 5 int j=nums.size()-1; 6 int middle; 7 while(i<=j) 8 { 9 middle=(i+j)/2; 10 if(nums[middle]<target) i=middle+1; 11 else if(nums[middle]>target) j=middle-1; 12 else return middle; 13 } 14 return -1; 15 16 } 17 };
27. 移除元素
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
*理解数组中的删除,实际上是覆盖
*快指针:找新数组元素;
*慢指针:指向更新的数组下标位置
解法一:暴力解法
1 class Solution { 2 public: 3 int removeElement(vector<int>& nums, int val) { 4 int len=nums.size(); 5 int i,j; 6 for(i=0;i<len;i++) 7 { 8 if(nums[i]==val) 9 { 10 for(j=i+1;j<len;j++) 11 { 12 nums[j-1]=nums[j]; 13 } 14 len--; 15 i--; 16 } 17 } 18 return len; 19 } 20 };
*删除一个元素后i需要后退一步
解法二:双指针法
1 class Solution { 2 public: 3 int removeElement(vector<int>& nums, int val) { 4 int i,j; 5 for(i=0,j=0;j<nums.size();j++) 6 { 7 if(nums[j]!=val) nums[i++]=nums[j]; 8 } 9 return i; 10 } 11 };
补充练习:
34. 在排序数组中查找元素的第一个和最后一个位置
1 class Solution { 2 public: 3 vector<int> searchRange(vector<int>& nums, int target) { 4 int rightborder=getright(nums,target); 5 int leftborder=getleft(nums,target); 6 if(leftborder!=-1&&rightborder!=-1) return{leftborder,rightborder}; 7 else return{-1,-1}; 8 } 9 private: 10 int getright(vector<int>& nums,int target) 11 { 12 int left=0; 13 int right=nums.size()-1; 14 int rightborder=-1; 15 int middle; 16 while(left<=right) 17 { 18 middle=(left+right)/2; 19 if(nums[middle]>target) right=middle-1; 20 else if(nums[middle]<target) left=middle+1; 21 else { 22 left=middle+1;//不能确定此时就是右边界,当作未找到在更新一次left 23 rightborder=middle; 24 } 25 } 26 return rightborder; 27 } 28 29 int getleft(vector<int>& nums,int target) 30 { 31 int left=0; 32 int right=nums.size()-1; 33 int leftborder=-1; 34 int middle; 35 while(left<=right) 36 { 37 middle=(left+right)/2; 38 if(nums[middle]<target) left=middle+1; 39 else if(nums[middle]>target) right=middle-1; 40 else 41 { 42 leftborder=middle; 43 right=middle-1;//同上 44 } 45 } 46 return leftborder; 47 } 48 };
两个函数,重点注意当找到目标元素时,还需要确定是不是左/右边界,需要再执行一次循环。
35.搜索插入位置
比704多了 当目标元素不存在是返回按序插入的位置 的返回值
注意返回值即可
1 class Solution { 2 public: 3 int searchInsert(vector<int>& nums, int target) { 4 int left=0; 5 int right=nums.size()-1; 6 int middle; 7 while(left<=right) 8 { 9 middle=(left+right)/2; 10 if(nums[middle]>target) right=middle-1; 11 else if(nums[middle]<target) left=middle+1; 12 else return middle; 13 } 14 return right+1; 15 } 16 };
今日小结
主要掌握二分法和双指针法,因为不久前刚做过所以相对很快也很顺利。其中34题上次没有做出来,这次根据自己的理解成功了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步