栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

算法基础-数组

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法基础-数组

0 数组

数组(array)是一种线性表数据结构,它用一组连续的内存空间来存储一组具有相同类型的数据。基本特点:支持随机访问,索引与寻址。java 中 int[] arr=new int[100];

1 动态数组

所谓动态数组就是其空间会随着数据量变化而变化(扩容或者缩容),比如java ArrayList C++ vector等都是动态数组。如果要实现一个动态数组需要怎么做?1)支持随机访问+寻址 2)空间怎么分配,怎么动态扩容,怎么缩容等
扩容做法:如果空间 不够,重新申请2倍空间大小,将数据拷贝新空间,然后释放旧空间
缩容做法:若空间利用率不到25%,则释放空间

在空数组中连续插入n个元素,来分析一下拷贝次数,数组最终长度2n,其由空间n->2n,拷贝n次数据,n是由n/2扩容到n,需要拷贝n/2 次,依次类推可以得出:总拷贝次数=n+n/2+n/4+…<2n的,可以看插入n个元素的均摊复杂度为o(1)
一次扩容到下一次释放,至少需要再删除0.5n次,比如刚扩容2n,那么至少删除0.5n数据才回触发缩容2n->n。思考一下扩容是2倍扩容,缩容为啥不是1/2空间阈值缩容。如果这么做话可能在临界情况插入和删除交替的话,就会触发扩容、缩容。

2 LeetCode 实战

合并有序数组 https://leetcode-cn.com/problems/merge-sorted-array/submissions/

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

主题思路:开辟一个新的数组,两个索引指针i,j 依次扫描数组数据,谁小先放谁
细节:需要考虑边界问题
具体代码如下。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        if(nums2==null || n<=0) {
            return;
        }
        int [] tmp=new int[m+n];
        int i=0,j=0,k=0;
        while(k=n||(i 

上面解法整体思路是没有问题,但是从空间复杂度耗费了o(m+n),有没有可以优化空间呢?由于最终数据是合并num1中,考虑能不能倒着放,先处理大的。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        if(nums2==null || n<=0) {
            return;
        }
        int i=m-1,j=n-1,k=m+n-1;
        while(k>=0) {
           if(j<0||(i>=0 && nums1[i]>nums2[j])) {
               nums1[k--]=nums1[i--];
           }else{
              nums1[k--]=nums2[j--];
           }
        }
    }
}


有序数组去重 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

主题思路:从头到尾扫描整个数组,如果这个元素和前一元素是否一样,不一样才保留
细节:边界和数组覆盖

```java
class Solution {
    public int removeDuplicates(int[] nums) {
        int i=0,k=0;
        for(i=0;i 

移动零 https://leetcode-cn.com/problems/move-zeroes/

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

主题思路:从头到尾扫描数组,保留要的元素,放到数组前面,然后把尾部数据处理成0
细节:边界

class Solution {
    public void moveZeroes(int[] nums) {
          int i=0,k=0;
          for(;i 

或者使用双指针法

class Solution {
    public void moveZeroes(int[] nums) {
      int i=0,j=0,len=nums.length;
      while(j
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/439724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号