力扣 704:二分查找
-
题目描述:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
题目链接:https://leetcode.cn/problems/binary-search/description/ -
解题思路:
题中给定的数组是升序排序,可以采用二分法以及暴力法进行查询。二分法查询的时间复杂度O(logn)比暴力法查询的时间复杂度O(n)要小。二分法查询的主要过程:找到该数组的中间元素,将中间元素与目标元素进行比较,判断出目标元素在数组的左半部分还是右半部分,再用相同的方法在数组的左/右半部分中进行查找,直到找到目标元素或发现该数组中不存在目标元素。 -
代码
int search(vector<int>& nums, int target) {
int left , right , middle;
left = 0;
right = nums.size() - 1;
while(left <= right){
middle = (left + right) / 2;
if(target > nums[middle]){
left = middle + 1;
}
else if(target < nums[middle]){
right = middle - 1;
}
else {
return middle;
}
}
return -1;
}
4. 注意事项
该代码片段中存在while循环,需要边界情况进行边界条件的选择。本代码在比较时采用的是[left,right],此时的边界条件就应该改为 left<=right,right = middle-1。若采用[left,right),边界条件就应该为 left<right,right = middle,此时若right = middle -1 且目标元素位于右边界时,就会出现返回-1即目标元素不在数组中,但此时目标元素是存在于数组中的。
力扣 27:移除元素
1. 题目描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
题目链接:https://leetcode.cn/problems/remove-element/
2. 解题思路:
此题可以使用快慢指针的方法,该方法基于数组删除只需要覆盖的特性。快指针进行数组遍历,慢指针用于表示更新,跟随新数组的增加而移动。使用快慢指针只用遍历一次数组,时间复杂度远低于暴力法。
3. 代码:
int removeElement(vector<int>& nums, int val) {
int slow;
slow = 0;
for(int i = 0; i < nums.size() ;i++){
if(nums[i] != val){
nums[slow] = nums[i];
slow = slow + 1;
}
}
return slow;
}
4. 注意事项:
双指针法可以大大减少程序运行的时间复杂度,在数组和链表中应用广泛。在使用双指针法时需要特别关注不同指针的移动条件,避免出现错误。
总结
在进行数组类型的题目时,可以根据已有的条件(包括:数组元素的排列顺序,操作等)进行方法选择,需要注意的是在数组中的增删操作的特殊性,并不能简单的进行增加与删除。在数组元素有序的情况下二分法是个不错的选择,对于乱序数组的查找可以先进行排序再进行二分法。双指针的思想十分重要,在数组和链表中可以进行考虑。