力扣刷题记录(Java)按代码随想录顺序——数组篇

文章介绍了二分查找算法在有序数组中的应用,讨论了区间定义对搜索策略的影响,并展示了如何在Java中使用双指针解决移除元素问题以及有序数组平方的非递减排序方法。
摘要由CSDN通过智能技术生成

704 二分查找

704. 二分查找icon-default.png?t=N7T8https://leetcode.cn/problems/binary-search/

题目描述:

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

解题思路:

有两个关键问题。

1. 如何定义区间?区间的定义决定whlie循环的条件。

一般会定义为左闭右闭区间或者左闭右开区间。

如果是左闭右闭区间,那么left<=right合法,如果是左闭右开区间,那么left<right合法。

2. target不等于nums[mid]时,区间端点如何变化?

以target<nums[mid]为例,此时target偏小。

如果是左闭右闭区间,区间右端点要到mid的左边,需要right=mid-1。因为如果right=mid的话,下一次搜索的区间又包括了mid,但是条件中已经说了target<nums[mid],所以下一次的区间不能含有mid。

如果是左闭右开区间,区间右端点要到mid的左边,right=mid即可,因为右边是开的。

两种情况的区间左端点一样,都是left=mid+1。因为左边都是闭的。

代码:

左闭右闭区间:

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while(left <= right){//左闭右闭区间,括号中是区间合法的条件
            int mid = (left + right) / 2;
            if(target < nums[mid])
                //target较小,要在左侧区间搜索。且nums[mid]不符合条件,左侧区间不能包含mid
                right = mid - 1;
            else if(target > nums[mid]) left = mid + 1;
            else return mid;
        }
        return -1;
    }
}

左闭右开区间:

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length;
        while(left < right){//左闭右开区间,括号中是区间合法的条件
            int mid = (left + right) / 2;
            if(target < nums[mid])
                //target较小,要在左侧区间搜索。且nums[mid]不符合条件,左侧区间不能包含mid
                right = mid;
            else if(target > nums[mid]) left = mid + 1;
            else return mid;
        }
        return -1;
    }
}

27 移除元素​​​​​​​27. 移除元素icon-default.png?t=N7T8https://leetcode.cn/problems/remove-element/题目描述:

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

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

解题思路:

如果不要求原地的话好办,新开一个数组,然后一个指针去遍历旧数组,不等于val的值就放到新数组中。但是本题要求空间复杂度O(1),那么就需要双指针。

fast用于遍历数组,slow作为新数组下标。(这个新数组不是新开空间的新数组,位置没有变,和nums是一个空间,只是含义变了)

fast是萝卜,slow是坑,把右边的萝卜填到左边的坑里。

fast什么情况都+1,slow符合条件才+1。(条件是fast指的值不是val)

代码:

class Solution {
    public int removeElement(int[] nums, int val) {
        int fast = 0, slow = 0;
        while(fast < nums.length){
            if(nums[fast] != val) nums[slow++] = nums[fast];
            fast++;
        }
        return slow;
    }
}

977 有序数组的平方

977. 有序数组的平方icon-default.png?t=N7T8https://leetcode.cn/problems/squares-of-a-sorted-array/

题目描述:

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

解题思路:

这个难在nums中可能有负数。要是都是正数,那不就直接平方了,原数组的顺序和平方后的顺序一样。有负数的话,可以想象,平方后大的数在左右两头。

那么就用双指针来处理,一个从最左边开始(i),一个从最右边开始(j),比较i和j所指数的大小,更大的那个放到新数组中。所以新数组从大到小来更新(下标k)。

由于语法忘了,此处加点java创建数组的小知识:

1. 声明并赋值

int[] arr = {1,2,4};

2. 声明数组名开辟空间并且赋值

int[] arr;
arr = new int[]{1,2,3};

3. 声明数组时指定元素个数然后赋值

int[] arr1= new int[3];
注意:最大元素下标为2,并且所有的元素值均为0
赋值一般用for循环

在Java中,当你声明并初始化一个基本类型数组,比如 int 类型的数组,它的每个元素都会被自动初始化为该类型的默认值。对于 int 类型的数组,每个元素的初始值是 0

创建数组,如果在创建的同时不初始化数组则必须指定其大小: int Array0=new int[3];

--------------------------------------------------------------------------
参考链接:

Java创建数组的方法_java new 一个数组-CSDN博客

Java 创建数组和初始化的几种方式总结 - 知乎

代码:

class Solution {
    public int[] sortedSquares(int[] nums) {
        int len = nums.length;
        int i = 0, j = len - 1, k = len - 1;
        int[] res = new int[len];
        while(i <= j){
            if(nums[i] * nums[i] > nums[j] * nums[j]){
                res[k--] = nums[i] * nums[i];
                i++;
            }
            else{
                res[k--] = nums[j] * nums[j];
                j--;
            }
        }
        return res;
    }
}

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值