美文网首页
数组与数组列表

数组与数组列表

作者: bowen_wu | 来源:发表于2022-08-09 10:06 被阅读0次

数组

  • 数组 => 由相同类型的元素的集合所组成的结构
  • 分配一块连续的内存来存储元素
  • 利用元素的索引可以计算出该元素对应的存储地址

特性

  • 在内存中为连续空间
  • 储存在数组中的元素是相同类型的
  • 通过 index 获取数组元素的时间复杂度是 O(1)

操作

  • 增 =>
  • 删 =>
  • 改 =>
  • 查 =>

沟通问题

  1. 什么类型的数组
  2. 是否有重复元素
  3. 是否有序
  4. 怎么输出 => 是全部结果还是任意结果
  5. 函数定义
    • 输入参数(几个,类型)
    • 输出(返回值)
    • 名字 => 具体意义
  6. 检查输入参数

K-Sum

  1. 排序
  2. 尝试遍历第一个数,将问题转化为 k-1 Sum
  3. 时间复杂度
    • 2-Sum => O(nlogn) + O(n) => O(nlogn)
    • 3-Sum => O(nlogn) + O(n^2) => O(n^2)
    • 4-Sum => O(nlogn) + O(n^3) => O(n^3)
    • k-Sum => O(nlogn) + O(n^(k-1)) => O(n^(k-1))

交换元素

引入中间变量

public void swap(int[] nums, int firstIndex, int secondIndex) {
   int temp = nums[firstIndex];
   nums[firstIndex] = nums[secondIndex];
   nums[secondIndex] = temp;
}

数组预处理技巧 - 前缀和

  • 快速计算一个区间内的元素之和
  • prefixSum[i] = \sum_{k=0}^{i-1}nums[k],i\not=0
  • prefixSum[0] == 0
  • 前缀和数组(prefixSum) length == nums.length + 1
  • nums[i] == prefixSum[i + 1] - prefixSum[i] => an = Sn - Sn - 1
  • interval[i, j] = prefixSum[j + 1] - prefixSum[i] => 从 i 到 j 的和 => Sj - Si = ai +1 + ai + 2 + ai + 3 + ... + aj
// 前缀和数组的长度为原数组长度加1
// 注意构造时 index 的取值范围
int[] prefixSum = new int[nums.length + 1];
for(int i = 0; i < nums.length; i++) {
   prefixSum[i + 1] = prefixSum[i] + nums[i];
}

数组列表 ArrayList

  • 基于数组实现的容量大小可动态变化的数据结构
  • 可以将很多数组操作的细节封装起来
  • List<Integer> list = new ArrayList<>();
  • get/set => O(1)
  • add/remove/indexOf => O(n)

ArrayList的实现

  1. 定义属性字段
    • 在数组的基础上实现:储存数据信息 int data[]
    • 属性:data, size, capacity
  2. 定义构造器实现
  3. 定义方法
public class MyArrayList<T> {
    private final static int DEFAULT_CAPACITY = 10;
    private Object[] elements;
    private int capacity;
    private int size;

    public MyArrayList() {
        this.elements = new Object[DEFAULT_CAPACITY];
        this.capacity = DEFAULT_CAPACITY;
    }

    public MyArrayList(int capacity) {
        if (capacity < 0) {
            throw new RuntimeException("Capacity value must be positive");
        }

        this.elements = new Object[Math.max(capacity, DEFAULT_CAPACITY)];
        this.capacity = Math.max(capacity, DEFAULT_CAPACITY);
    }

    // 方法 -> 增删改查

    /**
     * Add the element into array list by index.
     *
     * @param index element index
     * @param value element value
     */
    public void add(int index, T value) {
        rangeCheckForAdd(index);

        if (size == capacity) {
            resize(2 * capacity);
        }

        if (index < size) {
            for (int i = size; i > index; i--) {
                elements[i] = elements[i - 1];
            }
        }

        elements[index] = value;
        size++;

    }

    /**
     * Add in the last position
     *
     * @param value element value
     */
    public void add(T value) {
        add(size, value);
    }

    /**
     * Remove the element according index.
     *
     * @param index the element index
     * @return removed element
     */
    public T remove(int index) {
        rangeCheck(index);
        T toRemoved = (T) elements[index];
        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }
        elements[--size] = null;

        return toRemoved;
    }

    // 删除所有值为 value 的元素?还是删除第一个?
    public void removeByValue(T value) {

    }

    /**
     * Set/Update element value by index.
     *
     * @param index    the element index
     * @param newValue the new value to set
     */
    public void set(int index, T newValue) {
        rangeCheck(index);
        elements[index] = newValue;
    }

    /**
     * Get element by index.
     *
     * @param index the element index
     * @return the element value
     */
    public T get(int index) {
        rangeCheck(index);
        return (T) elements[index];
    }

    /**
     * Get the index of first element equals to value.
     *
     * @param value
     * @return 第一个等于 value 的下标
     */
    public int indexOf(Object value) {

    }

    /**
     * Get the length of array list.
     *
     * @return
     */
    public int size() {
        return size;
    }

    /**
     * Determinate the array list is empty or not.
     *
     * @return the status.
     */
    public boolean isEmpty() {
        return size == 0;
    }

    private void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            throw new RuntimeException("The index is invalid! The index: " + index);
        }
    }

    private void rangeCheckForAdd(int index) {
        if (index < 0 || index > size) {
            throw new RuntimeException("The index for adding is invalid! The index: " + index);
        }
    }

    /**
     * Dynamic grow
     */
    private void resize(int newCapacity) {
        // 1. 扩成多大
        // 2. 原来元素怎么办
        Object[] newElement = new Object[newCapacity];

        for (int i = 0; i < size; i++) {
            newElement[i] = elements[i];
        }

        this.elements = newElement;
        this.capacity = newCapacity;
    }
}

知识点

  1. 数组遍历考虑越界

相关文章

  • 数组与数组列表

    数组 数组 => 由相同类型的元素的集合所组成的结构 分配一块连续的内存来存储元素 利用元素的索引可以计算出该元素...

  • Python学习笔记(5):NumPy库入门1

    1. 列表与数组 列表:数据类型可以不同;数组:数据类型相同 2. ndarray: NumPy的数组对象 Num...

  • Perl 列表与数组(一)

    1. 理解含义 列表(list):标量的有序集合。 数组(array):存储列表的变量。 2. 列表与数组的异同 ...

  • 2.4Numpy的广播机制

    Numpy数组操作 数组广播机制: 数组与数的计算: 在Python列表中,想要对列表中所有的元素都加一个数,要么...

  • 前端的基本操作

    数组以及操作方法 在JavaScript中数组就是类似与Python中的列表 其实数组也是一种object 数组的...

  • Perl-2-列表与数组

    一、简介 列表:标量的有序集合 数组:储存列表的变量区别:列表指的是数据,数组指的是变量,列表的值不一定要放在数组...

  • 2018年9月29日.NET笔试面试题

    数组列表和数组有什么区别? 数组即Array类,数组列表即ArrayList类,两者非常相似,不过Array类在S...

  • perl-three(2018-05-26)

    第三章 列表和数组 标量代表单数,那么列表和数组就代表复数。 列表是标量的有序集合(指的是数据),数组是存储列表的...

  • R的数组和列表基本操作:创建与访问

    数组 创建数组array() array(向量名,维度说明,dimnames = list(维名称列表)) 列表 ...

  • golang 数组与切片

    1. 切片与数组对比 (1). 列表数组是具有固定长度且拥有零个或者多个相同数据类型元素的序列。数组的长度是数组类...

网友评论

      本文标题:数组与数组列表

      本文链接:https://www.haomeiwen.com/subject/ppbswrtx.html