原题链接:leetcode704二分查找
第一次运行显示出现了函数的返回绘制路径有错误,我只能表示无奈,因为C++基本语法问题真的好多不清楚,没辙,只能一点点补。
【初次题解思路】根据以前学过的二分法,从1/2数组元素处开始出发,判断是否与目标值相等,相等返回下标,不相等进入第二重判断,如果大于目标值,则当前的下标在目标值右侧,向左移动1/2的下标路程,如果小于则向右移动至i+i/2下标处。限制条件为i<10000;
【收获1】使用二分法查找的前提:
1.数组为有序数组;
2.数组中无重复元素;
【收获2】
vector&nums
vector是一个容器,它的底层原理也是数组。所以对数组的一些功能函数也可以用在nums上。
【收获3】二分法求解思路分两种,两种方法存在些微的区别,原理相同。
1.左闭右开[left,right],更新后的区间不包括更新前的middle,因为在前一次的判断中已经将其包括在内。
2.左闭右开[left,right]更新后的区间包括更新前的middle
int right=nums.size();
int middle=left+((right-left)>>1);
先定义一个left=0,作为左侧下标值,right=nums.length()+1作为右侧下标。初次查找范围是整个数组,每次查找范围[left,right]的中值,相等就直接返回下标right,不相等就向左右最大子区间的mid值进行移动,即让right=1/2*(left+right),或者让right=right+1/2*(right-left),如此不断实现一次次的移动,使查找范围变为原来的1/2,1/2的1/2,1/2的1/4……直到找到目标值target,返回当前的下标right,也就是mid的值,如果查找范围·已经到了边界,还没有找到,那么target不在所给的数组中,结束查询后返回值为-1.
左右下表都是有可能移动的,如果当前的mid大于或等于target,就表明target在当前的[left,mid]中,就让right=mid;反之,如果mid小于等于target,则表示target在[mid,right]中,就使left=mid;
接着进入下一轮的判断和数组更新。
下面是求解的源代码:
class Solution {
public:
int search(vector& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right)
{
int mid=(right-left)/2 + left;
int num=nums[mid];
if(num==target)
{return mid;}
else if(num>target)
{
right = mid - 1;
}
else {
left = mid + 1;
}
}
return -1;
}
};
【收获4】
在第一次的求解中,用到了for写循环,在返回值这里出现了问题
在写循环时,以往我习惯使用for,除了for循环还有其他的循环结构,比如这道题用到的:
while(left<=right)
{
}
%只要左侧的索引是小于等于右侧的索引就执行循环,直到不满足这个条件
【收获5】涉及到移位的运算
int middle = left +((right-left)>>1);
原题链接leetcode27移除元素
第一次求解中,报错原因是返回值没写,准确说不知道返回值是什么了,题目给出的返回方式有点没看明白。用了循环检索出和目标val相等的数组元素,nums[i],然后用下一个nums[i+1]覆盖掉nums[i],利用第二重循环,把后面的把前面的依次覆盖掉。
for(int i;i
暴力求解:
class Solution {
public:
int removeElement(vector& nums, int val) {
int size=nums.size();
for(int i=0;i
【收获1】容器vector不能使用nums.length(),但是可以使用nums.size()
【收获2】同向双指针法删除元素
定义两个指针,快指针用来寻找目标val;慢指针用来指向更新,新数组下标的位置
先定义一个慢指针
int slowIndex = 0;
用一个快指针检索出val,如果这个nums[fastIndex]不是val,就让慢指针指向这个新的数组元素
for( int fastIndex = 0 ; fastIndex < nums.size() ; fastIndex++)
{
if( val != nums[fastIndex] )
{ nums[slowIndex++] = nums[fastIndex] ;
}
}
这种求解方法的源代码:
class Solution {
public:
int removeElement(vector& nums, int val) {
int slowIndex=0;
for(int fastIndex=0;fastIndex
【收获3】
双向双指针求解左右开弓,尽量让更少的元素移动,这种解法相当于对上一种元素的优化。
如果做指针left指向的元素等于val,此时将右指针right指向的元素复制大左指针left的位置,然后右指针right左移一位,如果赋值过来的元素恰好也等于val,可以继续把右指针right指向的元素赋值过来(左指针left指向的等于val的元素的位置继续被覆盖),直到左指针指向的元素的值不等于val为止。
当左指针与右指针重合时,左右指针遍历完数组中的元素。
求解源代码:
class Solution {
public:
int removeElement(vector& nums, int val) {
int left = 0,right = nums.size();
while(left < right){
if(nums[left]==val){
nums[left]=nums[right-1];
right--;
}else {
left++;
}
}
return left;
}
};