leetcode算法练习——704.二分查找/27.移除元素

leetcode算法练习

704.二分查找

题目链接

思路:已经排好序 设置left mid right三根指针 根据mid指向的值和target目标值进行大小判断来决定left right指针的移动

注意点:
1. while中(left < 还是 < = right)
2. 循环里 right = mid 还是 = mid -1
3. 选取范围是[left, right] 还是 [left, right)
要根据3选取的范围是[left, right] 还是 [left, right) 来决定 1,2两点

方法一:左闭右闭[left, right]区间

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        // 考虑到while的区间应该是合法的 那么在 闭区间[left, right] 中:left == right 是合法的 既然合法就要在while中进行判断 故应该是 while(left <= right)
        while(left <= right){
        	// 为防止越界
            int mid = left + (right - left) / 2;
            if(target == nums[mid]){
                return mid;
            }else if(target > nums[mid]){
            // 原理同下
                left = mid + 1;
            }else if(target < nums[mid]){
            // 考虑到现在是 闭区间[left, right]中 已经判断过nums[mid] > target 那么mid一定不是要搜索的值 那么接下来的区间 一定不要包含 mid 这个值 既然不包含 那么接下来的区间应该是[left,mid-1] 不能把不在查找范围里的值包括进去
                right = mid - 1;
            }
        }
        return -1;
    }
}

方法二:左闭右开[left, right)区间

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        // 不包含右边界
        int right = nums.length;
        // 在左闭右开区间[left, right)中 left == right 是不合法的 故在while中应该是<
        while(left < right){
            int mid = left + (right - left) / 2;
            if(target == nums[mid]){
                return mid;
            }else if(target > nums[mid]){
            // 左闭右开区间[left, right) 包含left 现在已经明确了mid不是target 那么下一个搜索区间就不能包括mid 所以left = mid + 1
                left = mid + 1;
            }else if(target < nums[mid]){
            // 考虑到现在是 左闭右开区间[left, right)中 即不包含right 那么下一个区间应该不包含mid所在的数值 所以right = mid
                right = mid;
            }
        }
        return -1;
    }
}

27. 移除元素

题目链接

思路:
暴力解法:找到需要移除的元素 把后面的元素都往前移
双指针:利用快慢指针来更新新数组

注意:
1. 暴力解法中:往前移动的元素 还是需要与target进行比较 否则就会出错
2. 双指针:理解快慢两个指针的作用

方法一:暴力解法

class Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for(int left = 0; left < len; left++){
            if(nums[left] == val){
                for(int right = left + 1; right < len; right++){
                    nums[left] = nums[right];
                }
                // 因为下标i以后的数值都向前移动了一位 所以i也向前移动一位 这样才不会漏判
                left--;
                len--;
            }
        }
        return len;
    }
}

方法二:双指针

快指针:寻找新数组(删除目标之后的元素组成的数组)所需要的元素
慢指针:新数组的下标值 即需要更新的下标
快指针取到的值赋值给慢指针即可

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
        // 当不为目标值的时候 就把快指针指向的值给到慢指针指向的位置 也就是一直在更新新数组
            if (nums[fastIndex] != val) {
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        // 慢指针最后指向的位置就是新数组的大小
        return slowIndex;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值