代码随想录训练营D1-数组篇 day1 |力扣704二分查找、27移除元素

代码随想录训练营D1-数组篇 day1 |力扣704二分查找、27移除元素

文章中图片均来自于代码随想录代码随想录

1. 数组理论基础

1.定义:数组是存放在连续内存空间上的相同类型数据的集合。
2.较于链表的优势:随机存取。
数组的连续内存空间

3.二维数组:先行后列,横行竖列
二维数组

3.1 c++
(使用C++要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。)
c++中二维数组在内存中是连续的

void test_arr() {
    int array[2][3] = {
		{0, 1, 2},
		{3, 4, 5}
    };
    cout << &array[0][0] << " " << &array[0][1] << " " << &array[0][2] << endl;
    cout << &array[1][0] << " " << &array[1][1] << " " << &array[1][2] << endl;
}

int main() {
    test_arr();
}

//输出结果如下:是连续的
//0x7ffee4065820 0x7ffee4065824 0x7ffee4065828
//0x7ffee406582c 0x7ffee4065830 0x7ffee4065834

3.2 java中二维数组在内存中不是连续的

public static void test_arr() {
    int[][] arr = {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {9,9,9}};
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);
    System.out.println(arr[3]);
}

java中二维数组的内存模式

2.Leetcode704 二分查找

题目链接

1.二分查找:
数组nums内元素升序排列,给定目标元素target,若数组中有对应元素则返回其下标,若无该元素则返回-1。

2.基本思路:
在头、尾分别设置一个指针;计算出中间位置元素的下标 mid。若nums[mid]的值比targat小,则在后半段中继续找target;否则在前半段中找。

3.边界问题
在写代码时,关于数组下标的边界问题,大致有两种思路。思路一:左闭右闭 即[0, length-1]
思路二:左闭右开 即[0, length)
在写代码前先选定一个思路,然后在过程中都按着这种思路去写边界。

2.1 左闭右闭

public int search(int[] nums, int target) {

    //左闭右闭
    int i = 0;
    int j = nums.length - 1;
    int mid;

    //while循环中是 i <= j? 还是 i < j ?
    //考虑极限情况,在左闭右闭的条件下,i,j为同一下标是否合法?
    //[1,1] 是合法的,所以i,j可以相等
    while(i <= j){
        mid = (i + j) / 2;
        if(nums[mid] == target){//找到目标值,返回
            return mid;
        }else if(nums[mid] < target){//数组中间值 < 目标值;则目标值在右半侧
            //条件为左闭右闭,且右侧区间的左端点为mid + 1;
            i = mid + 1;
        }else {//nums[mid] > target
            j = mid -1;
        }
    }
    return -1;
}

2.2 左闭右开

//左闭右开[0, length)
public int search1(int[] nums, int target) {
    int i = 0;
    int j = nums.length;//右开
    int mid;

    //while循环中是 i <= j? 还是 i < j ?
    //考虑极限情况,在左闭右开的条件下,i,j为同一下标是否合法?
    //[1,1) 不合法的,所以i,j 不能相等
    while(i < j){
        mid = (i + j) / 2;
        if(nums[mid] == target){//找到目标值,返回
            return mid;
        }else if(nums[mid] < target){//数组中间值 < 目标值;则目标值在右半侧
            //条件为左闭右开,且右侧区间的左端点为mid + 1;
            i = mid + 1;
        }else {//nums[mid] > target
            //条件为左闭右开,左侧区间右端点应取到mid - 1;但这里是右开,所以j=mid;
            j = mid;
        }
    }
    return -1;
}

3.Leetcode27 移动元素

思路:快慢指针。
这里for循环中的i即为快指针,n为慢指针。快指针是为了找要存入的元素,而慢指针是在记录新数组中元素的位置。

//给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
public int removeElement(int[] nums, int val) {

    int n = 0;//待插入位置指针。数值不为val时,后移;数值为val 不动。
    int length = nums.length;

    //遍历时将 元素 移动到待插入位置
    for(int i = 0; i < length; ++i){
        nums[n] = nums[i];
        if(nums[i] != val){
            ++n;
        }
    }
    return n;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值