Leetcode刷题 Day1 数组:二分法,双指针

数组:基础数据结构,考查代码掌握能力

需要注意的点:

1.数组下标从0开始

2.数组内存空间地址是连续的

数组寻址

  • 数组在内存空间的地址是连续的,所以在删除增添元素的时候,需要移动其他元素的地址。
  • 数组元素不能删除,只能覆盖

一维数组在堆上连续的内存空间直接存储值。

二维数组:不同的语言对内存管理的方式不同:

  • C++:二维数组地址连续分布,每一维数组中的地址也连续分布
  • Java:Java没有指针,同时也不对程序员暴露其元素的地址,寻址操作完全交给虚拟机。

Leetcode原题1:704-二分查找

704. 二分查找 - 力扣(LeetCode)

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

示例 :

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

Java代码 

class Solution {
    public int search(int[] nums, int target) {
        for(int i=0;i<nums.length;i++)
        {
            if(nums[i]==target)return i;
        }return -1;
    }
}

时间复杂度:O(nums.length)        空间复杂度:O(1)

优化:二分法

由于题面给出的数组是升序排列,故上述代码借此之便,但存在复杂度较高的问题。我们需要对查找的过程进行优化

常用的查找算法:【查找算法】6种常见的查找算法简述及Python代码实现-CSDN博客

此处介绍二分查找:

首先,定义三个指针left,mid,right。其本质是用nums[mid]与target比较,但对于不同的区间,如[left,right)或者[left,right],left与right之间的小于关系是不一样的

  • 区间为[left,right],则分支结构判断条件为while(left<right)
  • 区间为[left,right),则分支结构判断条件为while(left<=right)

对于第一种写法,代码如下

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

对于第二种写法,代码如下

class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length;    //不用-1了
        while(left<right){
            int mid=(left+right)>>1;    //防止溢出
            if(nums[mid]>target)
            {
                right=mid;
            }
            else if(nums[mid]<target)
            {
                left=mid+1;
            }
            else return mid;
        }return -1;
    }
}

Leetcode原题2:27-移除元素

27. 移除元素 - 力扣(LeetCode)

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

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

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

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

Java代码

class Solution {
    public int removeElement(int[] nums, int val) {
        int slow=0;
        for (int x : nums)
        {
            if(x!=val){
                nums[slow++]=x;
            }
        }return slow;
    }
}

双指针法

在此题中,nums中的x为快指针指向的数组元素,慢指针为自定义的slow。图解如下:

  • 33
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值