代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。

一.二分查找

题目描述:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。


自己的思路:

分为两种情况:

1.数组中不存在要找的数

        1.1.target小于最小值或target大于最大值

        1.2.taget大于最小值并小于最大值

                1.2.1.那么这种情况只能是夹在两个数中间了

2.数组中存在要找的数

然后是定义两个指针,移来移去,这里面我还存在比如说什么时候取小于,什么时候取小于等于这些操作符有些混淆的问题。

然后脑子里想了想,比如说要找的是2.5,数组中相邻的两个是2,3,那么i一定等于j,不会出现j==k的情况。

package 二分查找;

public class _704 {
    public int search(int []nums,int target){
        int n = nums.length;//数组的长度
        int j = 0;//左边指针
        int k = n-1;//右边指针

        /*target小于数组中的最小值或大于最大值,直接返回-1*/
        if (target<nums[0]||target>nums[n-1]){
            return -1;
        }
        /*要去里面找*/
        while(j<=k){
            if (j+1==k&&nums[j]<target&&target<nums[k]){
                return -1;
            }
            if(target==nums[j]){
                return j;
            }else if(target==nums[k]){
                return k;
            }
            int i = (j+k)/2;
            if (target<nums[i]){
                k=i;
            }else if (target>nums[i]){
                j=i;
            }else if (target==nums[i]){
                return i;
            }
        }
        return -1;
    }
}

根据我自己脑子里想想写的方法,这是写的结果,等下我去看下博客和视频看下有没有提升。

 看了下视频,有两个可以提升的地方,一个是没有考虑好左闭右闭区间的问题,一个是取中间值的时候重复判断了,现在去重新ti

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;//数组的长度
        int j = 0;//左边指针
        int k = n-1;//右边指针

        /*第一种情况,target小于数组中的最小值或大于最大值,直接返回-1*/
        if (target<nums[0]||target>nums[n-1]){
            return -1;
        }
        /*第二种情况,要去里面找*/
        while(j<=k){
            int i = (j+k)/2;
            if (target==nums[i]){
                return i;
            }else if (target<nums[i]){
                k=i-1;
            }else if (target>nums[i]){
                j=i+1;
            }
        }
        //如果上面while循环结束还没有找到,那么就是夹在中间的情况,直接返回-1
        return -1;
    }
}

没什么提升,但是思路清晰了很多。

二.移除元素

题目描述:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路:

因为要求是O(1),而且不需要考虑超出新长度后面的元素,所以脑子里想到是交换,先写一下,看看对不对。

package 移除元素;

public class _27 {
    public int removeElement(int[] nums, int val) {
        int j = 0;
        for (int i=0;i<nums.length;i++){
            if (nums[i]==val){
                j++;
            }
        }
        /*
        * 1.现在知道数量了,如果有5个,把这5个移到数组后面去;
        * 2.如果后面5个中已经包含了val,保留,只需移动前面几个
        * */
        if (j==0){
            return nums.length;
        }else{
            for(int i =0;i<nums.length;i++){
                if (nums[i]==val&&i<nums.length-j){
                    for (int k=nums.length-j;k<nums.length;k++){
                        if (nums[k]!=val){
                            int temp=nums[i];
                            nums[i]=nums[k];
                            nums[k]=temp;
                        }
                    }
                }
            }
        }
        return nums.length-j;
    }
}

 

去看下视频。

讲了一个快慢指针的操作,直接把时间复杂度度变成O(n)了,是真的牛逼。

class Solution {
    public int removeElement(int[] nums, int val) {
        int i = 0;//慢指针,指向新数组的下标
        int j = 0;//快指针,指向符合新数组条件的数的下标
        for (;j<nums.length;j++){
            if (nums[j]!=val){
                nums[i]=nums[j];
                i++;
            }
        }
        return i;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值