算法通关村第三关———不简单的数组增删改查

大家好,我是Ryan,今天和大家分享一下数组的基础知识。

首先我们认识一下线性表,线性表就是具有相同特征数据元素的有限序列,所含元素个数叫做线性表的长度。

  • 语言实现角度来分,C语言是一体式结构,Java是分离式结构。
  • 存储角度来分,可以分为顺序型链表型

数组

在大多数语言中,数组中元素的索引都是从0开始,比如arr[0],加入数组的长度是len,那么数组的最后一个位置是arr[len-1]

还有个需要注意的是数组的大小和实际元素个数往往是不同的。比如创建一个大小是100的数组arr[100],但是里面只有a[0] 到a[9]这10个位置有数据,那他的size就是10。

初始化

记住一个很重要的初始化方式:

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

int[] arr1 = new int[10];

int[] arr2 = new int[]{1, 2, 3, 5}
添加或删除一个元素

数组添加或删除元素代价比较大,因为需要对元素进行移动。所以使用数组时尽量不对其进行增删操作,如果需要,可以使用链表。有一个原则就是如果你真的相对数组进行大量的增删操作时,你应该先考虑是不是数据结构选择错了

数组合并

最后讲一下数组合并的内容。题目 leetcode88

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是[1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

这道题有个简单的思路:

由于num1的长度是m+n,所以可以将num2拼接到num1后面再对num1进行排序。

不过上面那个太简单了,我们还可以接著一个新数组num3,遍历num1和num2时按照大小存到num3,这是算法的空间复杂度就是O(n),那能不能优化到O(1)呢?思考一下。

答案是可以的。因为num1后面的元素是空余的,所以我们可以从两个数组的后面开始比较,将较大的数放到后面,一直到全部放完。这时就不用借助额外空间。

接下来给出具体代码

public static void merge3(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
        int indexA=nums1_len-1;
        int indexB=nums2_len-1;
        int index=nums1_len+nums2_len-1;
        while (indexA>=0&&indexB>=0){
            nums1[index--] = 
            	nums1[indexA] >= nums2[indexB] ? nums1[indexA--]
            								   : nums2[indexB--];
        }
        //假如B数组还有剩余
        while (indexB>=0){
            nums1[index--]=nums2[indexB--];
        }
    }

这里最后只考虑了B数组有剩余,为什么不考虑A有剩余呢?思考一下。

如果数组A还有剩余元素,但数组B已经没有剩余元素,那么我们不需要做任何事情。因为数组A的剩余元素已经在正确的位置上,我们不需要移动它们。这就是为什么我们只需要处理数组B还有剩余元素的情况。

好了,本次就先讲这么多,下次再见。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值