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

算法通关村第二关——爱不起的数组

线性表

  1. 线性表的定义

    具有相同特征数据元素的一个有限序列,其中所含元素的个数称为线性表的长度

    1. 语言实现的角度:一体式©和分离式(java)

    2. 存储的角度:顺序型和链表型

      1. 顺序型:将数据存放在一段固定的区间内
      2. 链表型:元素之间通过地址依次连接的
    3. 访问限制的角度:栈和队列

      1. 队列
      2. Hash
    4. 扩容的角度

      1. 分离式结构顺序表,容量可以动态变化
      2. 每次固定数目的扩充
      3. 每次扩充一倍的存储空间
      4. 每个语言的扩充策略均不一样

数组

定义:线性表最基本的结构。元素是一个紧密在一起的序列。相互之间不需要记录彼此的关系就能访问

索引:数组的索引是从0开始

注意:

  1. 数组的空间不一定是满的,即size(数据个数的变量)不等于length(数组长度)

  2. 数组的初始化值为0

  3. 初始化必须是连续的初始化,中间不可以出现空缺的情况,但是尾部是有空缺的情况

  4. 数组的创建和初始化

            //1.初始化1
            int[] arr = new int[10];
            for (int i = 0; i < arr.length; i++) {
                arr[i]= i;
            }
            //2.初始化2
            int[] arrs = new int[]{0,1,2,3,4,5,6,7,8};
    
  5. 查找一个元素

        /**
         * 查找元素
         * @param
         * @return
         */
        public static int findByElement (int[] arr,int size, int key) {
            for (int i = 0; i < size; i++) {
                if (arr[i] ==key){
                    return i;
                }else if (arr[i] >=key){
                    return -1;
                }
            }
            return -1;
        }
    
  6. 增加一个元素

        /**
         * @param arr
         * @param size    数组已经存储的元素数量 从编号1开始
         * @param element 待插入的元素元素
         * @return
         */
        public static int addByElementSequence2(int[] arr, int size, int element) {
            //size表示元素的数量,arr.length表示数组容量,都是从1开始编号
            if (size >= arr.length){
                throw new IllegalArgumentException("Add failed. Array is full.");
            }
            for (int i = size; i > 0; i--) {
                if (arr[i-1]> element){
                    arr[i] = arr[i-1];
                }else {
                    arr[i] = element;
                }
            }
            return size+1;
        }
    
  7. 删除元素

        /**
         * 遍历数组,如果发现目标元素,则将其删除,
         * 数组的删除就是从目标元素开始,用后续元素依次覆盖前继元素
         *
         * @param arr  数组
         * @param size 数组中的元素个数
         * @param key  要删除的目标值
         */
        public static int removeByElement(int[] arr, int size, int key) {
            int index = -1;
            for (int i = 0; i < size; i++) {
                if (arr[i] == key) {
                    index = i;
                    break;
                }
            }
            if (index != -1) {
                for (int i = index + 1; i < size; i++)
                    arr[i - 1] = arr[i];
                size--;
            }
            return size;
        }
    

算法热身—单调数组问题

题目:LeetCode:896,判断该数组是否为单调数组

思路:题目简单,但是想要时间复杂度降低需要两个标识

解法:

    public boolean isMonotonic(int[] nums) {
        boolean inc = true, dec = true;
        int n = nums.length;
        for (int i = 0; i < n - 1; ++i) {
            if (nums[i] > nums[i + 1]) {
                inc = false;
            }
            if (nums[i] < nums[i + 1]) {
                dec = false;
            }
        }
        return inc || dec;
    }

题目:LeetCode:35. 给定一个排列数组和目标值,在数组中找到目标值,并返回索引,如果目标值不存在数组中,则返回他顺序插入的位置

思路:高阶思想,利用二分查找来进行查询

解法:

  1. 二分法

    class Solution {
        public int searchInsert(int[] nums, int target) {
            int n = nums.length;
            int left = 0, right = n - 1, ans = n;
            while (left <= right) {
                int mid = ((right - left) >> 1) + left;
                if (target <= nums[mid]) {
                    ans = mid;
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return ans;
        }
    }
    
    

算法热身—数组合并专题

题目:LeetCode:88,合并两个有序数组,使得合并完之后还是有序数组

思路:常规思路没什么好说的,关键是空间复杂度低的高阶思路:向后插入,因为两个合并的都是有序数组,所以他们的最大值一定在最后

解法:

  1. 向后插入

        /**
         * 方法2:两个数组从后向前逐步合并
         *
         * @param nums1
         * @param nums1_len
         * @param nums2
         * @param nums2_len
         */
        public static void merge2(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
            int i = nums1_len + nums2_len - 1;
            int len1 = nums1_len - 1, len2 = nums2_len - 1;
            while (len1 >= 0 && len2 >= 0) {
                if (nums1[len1] <= nums2[len2])
                    nums1[i--] = nums2[len2--];
                else if (nums1[len1] > nums2[len2])
                    nums1[i--] = nums1[len1--];
            }
            //假如A或者B数组还有剩余
            while (len2 != -1) nums1[i--] = nums2[len2--];
            while (len1 != -1) nums1[i--] = nums1[len1--];
        }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值