【数组】理论基础、704 二分查找、27 移除元素

理论基础

1. 数组在内存中的存储方式:数组是 存放在 连续内存空间上的 相同类型 数据 的集合。

2. 数组可通过下标索引获取到下标对应的数据,如图:

  • 下标从0开始
  • 内存地址连续  ---->   插入/删除元素时需要移动其他元素地址

3. 数组元素不能删,只能覆盖。

4. 二维数组在内存的空间地址是否连续?

        C++是,Java不一定。

704 二分查找

主要的两个问题

1. while循环中left < / <= right?

2. nums[middle]>target时,right = middle / middle - 1?

区间搜索中,需要确定的区间定义:

        []

        [)

主要是上面两种,也有(]

区间定义,为循环不变量,循环期间,一直不变的原则。

1. []写法:

        左右边界:

             left=0;

             right=nums.size-1;

        while循环:

             while(left  <=  right) 合法区间 {

                     middle=(left+right)/2;

                     if(nums[middle]>target){    middle一定不是要搜索的值

                             right=middle-1;

                    }else if(nums[middle]<target){

                             left=middle+1;

                    }else{

                             return middle;

                    }

             }

             return -1;

2. [)写法:

        不包含right

        左右边界:

             left=0;

             right=nums.size;

        while循环:

             while(left  <  right) 合法区间 {

                     middle=(left+right)/2;

                     if(nums[middle]>target){  开区间取不到

                             right=middle;

                    }else if(nums[middle]<target){

                             left=middle+1;

                    }else{

                             return middle;

                    }

             }

             return -1;

补充:

        1. 区间概念:二分查找是通过在变换区间里比较来查找target的;

        2. 对边界的处理(右开/右闭),用于确定循环不变量;

        3. 中点防溢;🌼

                (left + right)/2

leftright 都是较小的正整数时,left + right 可能会导致整数溢出。但是,如果 leftright 都是正整数,并且他们的和不会导致溢出,那么 (left + right) / 2 就是一个有效的计算方式。

                left + (right - left)/2

  • 这种方式首先计算了 right - left,这是一个正数。因为 right 大于等于 left,所以 right - left 不会导致溢出。
  •  计算 left + (right - left) 不会导致溢出,因为 right - left 是一个小于 right 的正整数,加上 left 不会使结果溢出。

        4. 中点偏左/偏右?偏左

27 移除元素

内存地址连续  ---->   插入/删除元素时需要移动其他元素地址

数组元素不能删,只能覆盖。

erase函数复杂度O(n)

暴力解法

        两层for循环,一层遍历数组,一层更新数组。

双指针法(快慢指针)

        快指针fast:指向新数组中需要的元素

        慢指针slow:新数组的下标索引

slow=0;

for(fast=0; fast<nums.size; fast++){

        if(nums[fast]!=val){   更新数组

                nums[slow]=nums[fast];

                solw++;

        } 

}

return slow;

slow++可以直接放在nums[slow++]中.

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值