【代码随想录刷题记录】704.二分查找、27移除元素

力扣 704:二分查找

  1. 题目描述:
    给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
    题目链接:https://leetcode.cn/problems/binary-search/description/

  2. 解题思路:
    题中给定的数组是升序排序,可以采用二分法以及暴力法进行查询。二分法查询的时间复杂度O(logn)比暴力法查询的时间复杂度O(n)要小。二分法查询的主要过程:找到该数组的中间元素,将中间元素与目标元素进行比较,判断出目标元素在数组的左半部分还是右半部分,再用相同的方法在数组的左/右半部分中进行查找,直到找到目标元素或发现该数组中不存在目标元素。

  3. 代码

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

力扣 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. 注意事项:
双指针法可以大大减少程序运行的时间复杂度,在数组和链表中应用广泛。在使用双指针法时需要特别关注不同指针的移动条件,避免出现错误。

总结

在进行数组类型的题目时,可以根据已有的条件(包括:数组元素的排列顺序,操作等)进行方法选择,需要注意的是在数组中的增删操作的特殊性,并不能简单的进行增加与删除。在数组元素有序的情况下二分法是个不错的选择,对于乱序数组的查找可以先进行排序再进行二分法。双指针的思想十分重要,在数组和链表中可以进行考虑。

你可能感兴趣的:(leetcode)