day1 二分查找 移除元素
Problem: 704. 二分查找
二分查找
这是一个左闭右闭的二分查找算法,一个数组的大小是N,因为是从0开始。首先需要把这个数组全部放进来,所以放进数组的应该是0
~
N-1。如果使用左闭右闭,刚刚好是0~
N-1,但是如果是左闭右开的话,需要放的是0~
N,因为N取不到嘛。
所以,这里分为两种情况:左闭右闭和左闭右开,为什么没有左开右闭,原因很简单,如果要是左开右闭,想放入的数组是0~
N-1,那么需要左面为-1,也就是说放进去就是-1~
N-1,所以避免-1,就一般不设左开的情况。(这里的开闭其实是表示了容纳数组的一个情况)
以上是你选择的一个方法,也就是你可以选择两种方法来存放你要查找的数组。
接下来就是根据不一样的方法来确定不一样的判断策略:
左闭右闭
如果选择了左闭右闭的方法,意味着arr[0~
N-1]全部都是可以直接取得,所以在while循环中,就是while(left <= right),这里的left是0,right是N-1。
再接下来,逻辑还是很简单的,如果目标值比arr[middle]小,那么说明目标值在middle的左边,所以right = middle - 1。因为这里是右闭,所以右面的这个始终是可以取到的,所以你判断的有效内容就应该是(0~
middle-1),因为middle一定不符合,同理如果目标值比arr[middle]大,那么就去右边,因为左闭,所以也是(left+1~right)。
Code
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0,right = nums.size()-1;
while(left <= right)
{ int middle= (left + right) / 2;
if(nums[middle] < target)
{
left = middle + 1;
}else if(nums[middle] > target)
{
right = middle - 1;
}
else
{
return middle;
}
}
return -1;
}
};
左闭右开
左闭右开其实只有一点点区别,就是它放的有效区间的表示不一样了,为什么叫有效区间的表示呢?举个例子:
你要放入的区间是0~N-1
使用左闭右闭:[0,N-1]
使用左闭右开:[0,N)
有效区间一样,但是只是表示的不一样。
所以while(left < right),这里left是0,right是N,那能取到arr[N]吗?,明显取不到。
接下来是比较那里,其实和上面是类似的,如果target大于middle的话,和上面一样,因为左边是闭的,如果target小于middle的话,那个right = middle;不需要-1就可以了,因为你的middle肯定不满足,目的是不取它,然而你刚刚的while判断,刚好右开,所以完美的不取middle,所以也不用-1。
最后还有一点要注意, int left = 0,right = nums.size();这里right不是N-1
而是N,注意要改一下!
Code
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0,right = nums.size();
while(left < right)
{ int middle= (left + right) / 2;
if(nums[middle] < target)
{
left = middle + 1;
}else if(nums[middle] > target)
{
right = middle;
}
else
{
return middle;
}
}
return -1;
}
};
移除元素
Problem: 27. 移除元素
快慢指针删除数组元素
使用了快慢指针,这个主要是要知道数组中的删除其实是覆盖,也就是说只要是连续的覆盖,都可以使用快慢指针的方法来解决。
解题方法
使用快指针来遍历整个数组,然后把要删除的目标值跳过,即可。
跳过的方法也很简单:
if(num[fast] != val),这样就可以避开要删除的目标值,里面是你想做的,在这里,目标操作是要把要删除的目标值略过去,所以只需要让快指针遍历的时候,如果不是目标值,那就覆盖即可,覆盖完slow移到下一位,等待下一次的覆盖。
Code
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fast = 0,slow = 0;
for(fast = 0;fast < nums.size();fast++)
{
if(nums[fast] != val)
{
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};