给定一个
n
个元素有序的(升序)整型数组nums
和一个目标值target
,写一个函数搜索nums
中的target
,如果目标值存在返回下标,否则返回-1
。
思路:根据二分查找的思路缩小寻找范围,从而找到目标值。时间复杂度为O(logn),空间复杂度为O(1)
难点:搞不清楚到底该是left<=right,还是left<right;同时在缩小范围的时候也需要思考到底是right=mid+1还是right=mid
当采取左闭右闭原则时,right = nums.size() -1, while循坏采用 left<=right判断,缩小范围时,left = mid + 1,right = mid - 1;
当采取左闭右开原则时,right = nums.size(), while循环采用left<right判断,缩小范围时,left = mid + 1,right = mid;(因为本身左闭右开并不包含右边,所以当目标值出现在数组左边时,缩小范围right=mid)
//采用左闭右闭原则
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int mid = left + ((right - left) / 2);
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
//采用左开右闭原则
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left < right){
int mid = left + ((right - left) / 2);
if(nums[mid] > target){
right = mid;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素。元素的顺序可能发生改变。然后返回nums
中与val
不同的元素的数量。假设
nums
中不等于val
的元素数量为k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。- 返回
k
。
思路:两种方法求解,首先是暴力求解,在两个循环里面进行,此时时间复杂度为O(n^2),空间复杂度为O(1) ,这也是最常用的,当遇到val时,将后面的所有值往前移动覆盖,再记录下移动的个数,总数相减即可得到最终结果;第二种方法是双指针法,采用快慢指针进行,快的指针和慢的指针从同一起点出发,快的指针在前面探路,当遇到不是val的值时就将其传给慢的指针,慢的指针再往前挪,这样往复进行,得到最终结果。此时时间复杂度为O(n),空间复杂度为O(1)
难点:时刻注意下标的增减,以免出错。
int removeElement(vector<int>& nums, int val) {
int slow = 0;
for(int fast = 0; fast < nums.size(); fast ++){
if(nums[fast] != val){
nums[slow ++] = nums[fast];
}
}
return slow;
}
给你一个按 非递减顺序 排序的整数数组
nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。请你设计时间复杂度为
O(n)
的算法解决本问题
思路:题目看着很简单,数组中的数平方后,再按非递减顺序排列即可,但是这样的话至少都需要O(n+nlogn)的时间复杂度(先一个循环将每个数平方,在使用快排进行排序),显然不符合题目要求。因此此路是行不通了。
这里还是需要借助一下刚刚讲过的双指针思想。
首先,数组本身是非递减顺序,因此最右边的数是最大的,但是平方后不一定是最大的,比如有这样一组数-100,....,2,10,显然-100的平方最大,而不是右边的数;但是我们能确定一件事,那就是,最大的数一定存在在两端,不可能存在在中间,由此就和归并排序类似了,新建一个数组,然后用两个指针分别指向原数组两端,比较所指向的元素哪个大,最大的填入新数组内,即可解决该问题。
难点:指针下标的移动以及左右两个指针的边界条件的判断
这里我还想说一点,题目限制了时间复杂度,但是没有明确限制空间复杂度,或许最优解就是牺牲一方换一方,牺牲了空间换时间,此时空间复杂度为O(n),与输入数据规模成正相关。
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size() , 0);
int k = nums.size() - 1;
for(int i = 0, j = nums.size() - 1;i <= j;){
if(nums[i] * nums[i] > nums[j] * nums[j]){
result[k --] = nums[i] * nums[i];
i ++;
}else{
result[k --] = nums[j] * nums[j];
j --;
}
}
return result;
}
希望我的博客能够带给你一点帮助,我也还在学习中,如有问题,欢迎随时讨论