数组——简介&初始定义

数组

参考地址:https://leetcode-cn.com/leetbook/detail/all-about-array/

数组是在程序设计中,把具有相同类型的若干元素按有序的形式组织起来的一种形式。

作为线性表的实现方式之一,数组中的元素在内存中是 连续 存储的,且每个元素占相同大小的内存。

对于一个数组 ['oranges', 'apples', 'bananas', 'pears', 'tomatoes'],通过索引和数组第 1 个元素的内存地址,可以计算出其它元素的内存地址,进而访问内存地址里存储的内容。索引与内存地址的关系如下图所示。

数组通过 索引 快速访问每个元素的值。在大多数编程语言中,索引从 000 算起。

在不同的编程语言中,数组的实现方式具有一定差别。比如 C++ 和 Java 中,数组中的元素类型必须保持一致,而 Python 中则可以不同。相比之下,Python 中的数组(称为 list)具有更多的高级功能。

 

做好初始定义
1.移动零:

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

解法一:快指针遍历数组,慢指针指向0元素,快指针每次遇到非0,即将快慢指针指向的元素进行交换。代码如下:

class Solution {
    public void moveZeroes(int[] nums) {
        int slow = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i]!=0){
                swap(nums,slow,i);
                slow++;
            }
        }
    }
    void swap(int[] nums,int slow,int quick){
        int temp = nums[slow];
        nums[slow] = nums[quick];
        nums[quick] = temp;
    }
}

 

解法二:先对非0元素进行排序,剩余位置全部用0填充,代码如下:time-beat100%

class Solution {
    public void moveZeroes(int[] nums) {
        //非0排序
        int index = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i]!=0){
            nums[index++] = nums[i];
            }
        }
        while(index<nums.length){
            nums[index++] = 0;
        }
    }
}

 

2.移除元素:

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

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

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

题解:时间100%

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

 

错误:第一遍答案返回了 index+1;导致数组元素比正确答案多一个。

3.删除排序数组中的重复项:

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

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

题解:从数组下标1开始遍历,若当下元素与上一数组下标对应的元素一直,则跳过,否则将元素赋值给 慢指针对应的数组。

class Solution {
    public int removeDuplicates(int[] nums) {
        int index = 1;
        for(int i = 1;i < nums.length;i++){
            if(nums[i] == nums[i-1]){
                continue;
            }
            nums[index++] = nums[i];
        }
        return index;
    }
}
//time-beat 100%

 

4.删除排序数组中的重复项 II

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

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

题解:与上题题解的有所区别

  1. index 与 i 从 ‘1 ’ 变为 ‘2’

  2. 判断条件由与原数组下标进行对比变为与额外设置的新数组index下标进行对比。这是因为该题中对数组进行比较判断时跨了2个数组下标,若原地进行比较,某些情况下,会出现错误(例如 x,2,2,x 遍历到第一个 2时该元素可能 会被塞入第一个x的位置,判断第二个2时,此时由于第一个x原位置已经变更为2,因为程序会判断 出现3个连续的2 (此时数组元素为 2,2,2,x),因此比较对象,只能是原数组下标‘i’指向的元素,与新数组下标‘index’指向的元素进行比较,即每次想将旧数组元素塞入新 数组元素时,将预塞入元素与新数组中的元素进行比较,防止连续放入3个相同数字)

class Solution {
    public int removeDuplicates(int[] nums) {
        int index = 2;
        for(int i = 2;i < nums.length;i++){
            if(nums[i]!=nums[index-2]){
                nums[index++] = nums[i];
            }
        }
        return index;
    }
}
//time-beat 100%

 

posted @ 2022-02-21 14:03  lc已被占用  阅读(189)  评论(0)    收藏  举报