Lettcode精选(Java)--数组篇(二)

简介: Lettcode精选(Java)--数组篇(二)

4.有序数组的平方



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


示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]


示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]


双指针法


image.png


此时的时间复杂度为O ( n ) O(n)O(n)


package com.caq.array;
import org.junit.Test;
/**
 * 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
 *
 * @Date 2021/12/18 9:19
 * @Version 1.0
 */
public class SquaringAnOrderedArray {
    public static void main(String[] args) {
        int[] nums = {-4, -2, 0, 1, 2, 3};
        SquaringAnOrderedArray soa = new SquaringAnOrderedArray();
        int[] ints = soa.sortedSquares(nums);
        int[] ints1 = soa.sortArray(nums);
        for (int anInt : ints1) {
            System.out.println(anInt);
        }
    }
    /**
     * 思路分析:
     * 因为数组是有序的,数组元素平方后最大和最小的一定是在最前面或最后面不可能在中间
     * 所以我们定义两个指针,一个指向最前面,一个指向最后面
     * 我们将它们平方后的结果进行比较,结果大的放到一个新的数组里,这个新数组大小和老数组一样,但是我们把下标放到最后
     * 这样比一次得到一个最大值,放到后面指针前移即可
     *
     * @param nums
     * @return
     */
    public int[] sortedSquares(int[] nums) {
        //注意这两个都是数组坐标,一个在最前面,一个在最后面
        int left = 0;
        int right = nums.length - 1;
        //在定义一个放结果的数组,和指向新数组最后一个元素的索引
        int[] result = new int[nums.length];
        int index = nums.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return result;
    }
}


5.长度最小的子树组



给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。


示例:


输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。


滑动窗口


image.png


在本题中实现滑动窗口,主要确定如下三点:


窗口内是什么?

如何移动窗口的起始位置?

如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。


窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。


窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,窗口的起始位置设置为数组的起始位置就可以了。


可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O ( n 2 ) O(n^2)O(n

2

)的暴力解法降为O ( n ) O(n)O(n)。


package com.caq.array;
/**
 * @Date 2021/12/18 22:58
 * @Version 1.0
 */
public class SlidingWindow {
    public static void main(String[] args) {
        int[] nums = {1, 3, 5, 5, 6, 4, 3};
        SlidingWindow sw = new SlidingWindow();
        int i = sw.minSubArrayLen(8, nums);
        System.out.println(i);
    }
    public int minSubArrayLen(int s, int[] nums) {
        int n = nums.length;    //n是负责让end指针一直向右移动
        if (n == 0) {       //数组长度为0的话,直接退出
            return 0;
        }
        int ans = Integer.MAX_VALUE;    //定义一个最大的int值,和下面的Math.min()方法做对比
        int start = 0, end = 0;     //定义开始指针和结束指针
        int sum = 0;        //定义数组中元素的和
        while (end < n) {       //第一层循环,如果结束指针没有指到最后那么一直循环,当然这里用for循环也是一样的效果for (int end = 0;end<nums.length;end++){}
            sum += nums[end];       //没什么好说的就是遍历数组的元素,然后累加
            while (sum >= s) {      //这层循环控制的是什么呢?这里其实是为了寻找最短的子数组,发现满足条件之后,让起始指针后移看看满足不满足情况。通过这种方式来获取最小子数组
                ans = Math.min(ans, end - start + 1);       //这里得到的结果为子数组的长度
                sum -= nums[start];         //计算后移后的子数组的元素和
                start++;        //开始指针后移
            }
            end++;      //如果元素之和不满足目标,那么右指针一直向右移动
        }
        return ans == Integer.MAX_VALUE ? 0 : ans; //注意这里的ans == Interger.MAX_VALUE才是boolean
    }
}


相关文章
|
3月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
2月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
4月前
|
存储 Java 索引
java 数组
在 Java 中,数组是一种数据结构,用于存储多个相同类型的数据元素。数组的大小一旦创建后就不能改变,因此它是固定长度的。Java 数组是一种 对象,即使它存储的值是基本类型(如 int、double 等),它也是一个对象引用。
94 0
|
6月前
|
存储 人工智能 Java
打乱数组内容引发的问题( Java)
本文介绍了两种实现数组随机打乱的方法,并深入探讨了Java中原始数据类型与对象类型的差异。方法一通过自定义随机数交换数组元素位置,方法二借助`Collections.shuffle()`函数完成数组打乱。同时,文章详细解析了`int`和`Integer`的区别,包括声明方式、内存占用、初始化以及对象特性等,并讲解了自动装箱与拆箱的功能,帮助读者更好地理解Java的基础知识。
|
8月前
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
463 1
Java 中数组Array和列表List的转换
|
8月前
|
存储 监控 Java
《从头开始学java,一天一个知识点》之:数组入门:一维数组的定义与遍历
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 这个系列就是为你打造的Java「速效救心丸」!我们承诺:每天1分钟,地铁通勤、午休间隙即可完成学习;直击痛点,只讲高频考点和实际开发中的「坑位」;拒绝臃肿,没有冗长概念堆砌,每篇都有可运行的代码标本。明日预告:《多维数组与常见操作》。 通过实例讲解数组的核心认知、趣味场景应用、企业级开发规范及优化技巧,帮助你快速掌握Java数组的精髓。
152 23
|
8月前
|
存储 Java 索引
Java 复制数组
本文介绍了Java中数组的基础知识与常用操作,包括数组的概念、创建、访问元素、遍历、复制、排序和搜索等方法。同时详细讲解了数组的五种赋值方式,并通过代码示例演示了求总和平均值、最大最小值、升序降序排序及Arrays类的常用方法。内容深入浅出,适合初学者学习掌握Java数组的核心功能与应用场景。
|
7月前
|
存储 Java 数据挖掘
Java 中数组的多种定义方式
本文深入解析了Java中数组的多种定义方式,涵盖基础的`new`关键字创建、直接初始化、动态初始化,到多维数组、`Arrays.fill()`方法以及集合类转换为数组等高级用法。通过理论与实践结合的方式,探讨了每种定义方法的适用场景、优缺点及其背后的原理,帮助开发者掌握高效、灵活的数组操作技巧,从而编写更优质的Java代码。
276 0
|
10月前
|
存储 Java C++
Java数组:静态初始化与动态初始化详解
本文介绍了Java中数组的定义、特点及初始化方式。
558 12
下一篇
开通oss服务