代码随想录 -day1

前言

  • 系统的纪录一下刷算法的过程,之前一直半途而废,现在重新开始。话不多说,开冲!

数组理论基础

数组是存放在连续内存空间上的相同类型数据的集合

特点:

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址,数组的元素是不能删的,只能覆盖

复习下java数组在内存中的情况:

java中数组的内存分配

java数组内存图片

1、二分查找

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

  • 输入: nums = [-1,0,3,5,9,12], target = 9
  • 输出: 4
  • 解释: 9 出现在 nums 中并且下标为 4

leetcode27.移除元素

思路

有序数组,而且数组中无重复元素,这些二分法的前提条件

二分法容易想得到,但是就是经典一看就会,一做就错。

最重要的就是边界条件,(就在这里卡了半天,案例没问题,一提交力扣就错,tnnd)

代码随想录里面提供了两种思路:左闭右闭即[left, right],或者左闭右开即[left, right)

代码

左闭右闭

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

个人感觉这个更好理解,也不容易出错

    public static int search_1(int[] nums, int target) {
        int left=0;
        int right= nums.length-1;
        while (left<=right){//闭区间,可能存在left == right
            int mid=(right+left)/2;
            if (target>nums[mid]){
                left=mid+1;//因为mid所在的数字比较过了,这里要+1,下面同理
            }else if (target<nums[mid]){
                right=mid-1;
            }else if (target==nums[mid]){
               return mid;
            }
        }
        return -1;
    }

左闭右开

public static int search_2(int[] nums, int target) {
    int left=0;
    int right= nums.length;
    while (left<right){
        int mid=(right+left)/2;
        if (nums[mid]<target){
            left=mid+1;
        }else if (target<nums[mid]){
            right=mid;
        }else if (target==nums[mid]){
            return mid;
        }
    }
    return -1;
}

2、移除元素

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

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

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

  • nums = [3,2,2,3], val = 3

  • 2, nums = [2,2]

  • nums = [0,1,2,2,3,0,4,2], val = 2

  • 5, nums = [0,1,4,0,3]

leetcode704 二分查找

思路

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖

这里使用双指针法(之前刷过,但忘了具体怎么使用)

自己写时候的思路过程:

用双指针,指什么呢?后面的元素不要,是不是可以一前一后?然后把前面要删除的元素移后面去,后面指针就指向一个不需要移除的元素(想的很好,但写的差点意思)

代码

public static int removeElement(int[] nums, int val) {
    int left=0;
    int right= nums.length-1;
    //首先将右指针移到非移除元素下标(一开始这里我放在了for里面,用while确实好简洁)
    while (right>=0&&nums[right]==val){right--;}
    while (left<=right){
         if (nums[left]==val){
            int temp=nums[left];
            nums[left]=nums[right];
            nums[right]=temp;
            right--;
        }
         left++;
         //左右指针元素移了之后,右指针要指向一个非移除元素(就是这里没想到)
        while (right>=0&&nums[right]==val){right--;}
    }
    return left;
}




小感悟

二分错了4次,对比边界条件一无所知

移除元素试了两次没写出来,看题解去了

今天等于说一天没写出来,还是写之前写过了题目,淦!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值