代码随想录算法训练营Day1|704.二分查找 27.移除元素 977.有序数组的平方 (数组,双指针)

文章目录

  • 704.二分查找
    • 复盘:数组与指针的关系,语句之间的区别
    • 识别
    • 核心/易错点
    • 难点/亮点
    • 算法设计思路
    • 代码实现
  • 27.移除元素
    • 背景知识
    • 算法设计思路
    • 代码实现
  • 977有序数组的平方(左右双指针)
    • 识别
    • 核心/易错
    • 难点/亮点
    • 算法设计思路
    • 代码实现

#二分查找1if找到,2找到位置(更新查找范围,缩小区间)
6分37代码随想录,小鹅通32min,56min

704.二分查找

复盘:数组与指针的关系,语句之间的区别

识别

1.有序

核心/易错点

区间全闭while (left <= right),if判断middle不等target时,区间不包括middle。
用数组下标索引计算中间值。

难点/亮点

1,.在区间里搜索的时候,首先要对这个区间的定义一定要明确。这个区间它是左闭右闭,若为左闭右闭就是这个区间是包含left和right的,左闭右开不包含right这个值。
2.根据这个区间的定义在这个循环中是处理这两个边界条件。nums[middle] 一定不是我们搜索的值。

算法设计思路

1.判断数组元素中包含目标元素
2.若包含目标元素,将其与中间值比较(数组索引),
若目标元素>中间值
若目标元素<中间值
直到相等
变式验证合理(生成元素,有序)。

代码实现

有序数据,目标元素,中间值的计算(越界左+偏移量),查找search函数

int search(int* nums, int numsSize, int target) {
    if (numsSize == 0) return -1; // 处理空数组的情况

    int left = 0;
    int right = numsSize - 1;
    while (left <= right) {
        int middle = left + (right - left) / 2; // 计算中间索引,防止整数溢出=============时间复杂度主要区别
        if (nums[middle] < target) {
            left = middle + 1;
        } else if (nums[middle] > target) {
            right = middle - 1;
        } else {
            return middle; // 找到目标值,返回索引
        }
    }
    return -1; // 未找到目标值,返回-1
}

在这里插入图片描述在这里插入图片描述

27.移除元素

代码随想录9分22,12分44

快慢双指针,一头进
左右双指针,相向而行

背景知识

1.数组的内存发布
2.erase函数
erase函数里边的实现机制,它是一个O(n)的一个操作。
知道这个库函数里边的内部实现的过程。
3.库函数的使用
使用库函数仅仅是我们解决问题里边的其中一小
步以及它的时间复杂度。

算法设计思路

法1暴力解法:用一个for循环去遍历我们的这个数组再用一个循环把后面的元素一个一个的都向前覆盖。
法2双指针解法:快指针获取到的值赋给慢指针。
双指针的写法用一个O(n)的一个方式就来实现一层for循环做了刚才暴力解法两层for 循环要做的一个事情帮我们节省了一层for循环要做的事情。
1.定义一个快指针fast(快指针用来获取新数组中的元素)寻找这个新数组里所需要的元素即删除目标值之后的元素。
2.定义一个慢指针slow(获取我们新数组中需要更新的位置)。
快指针fast指向我们新数组所需要的元素获取到新数组所需要的元素之后给它赋给新数组的这个下标值就是慢指针slow需要更新的下标就是我们的这个慢指针slow。
3.当遇到需要更新的值时,快指针指向这个元素赋给我们新数组这个位置之后那么我们这个慢指针向后移动一个位置;
4.快指针先移动,遇到不需要更新的值时慢指针不移动,快指针再移动,即遇到不更新的值时快指针移动两次,慢指针不移动。
5.新数组的大小:慢指针所指向的这个位置即新数组中的大小(因为数组下标从0开始)。

代码实现

两头进
```C
/**,2个数组

 * Note: The returned array must be malloced, assume caller calls free().

 */

#include <stdlib.h>
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    // 分配内存来存储结果
    int* result = (int*)malloc(sizeof(int) * numsSize);
    if (result == NULL) {
        *returnSize = 0;
        return NULL; // 内存分配失败
    }

    int i = 0, j = numsSize - 1;
    int k = numsSize - 1; // 从数组末尾开始填充结果数组

    while (i <= j) {
        if (abs(nums[i]) > abs(nums[j])) {
            result[k] = nums[i] * nums[i];
            i++;
        } else {
            result[k] = nums[j] * nums[j];
            j--;
        }
        k--;
    }

    *returnSize = numsSize; // 设置返回数组的大小
    return result; // 返回分配的数组
}

在这里插入图片描述在这里插入图片描述

977有序数组的平方(左右双指针)

识别

有序数组

核心/易错

两个指针的一个操作而逐步向中间合拢的过程
得到了一个由大到小的一个数组

难点/亮点

for循环不写i++和j- -
因为i++和j-.-其实都是有条件的
何时i++,j- -(取决于也就是这两头的元素谁大)
3个索引:i,j,k,k- -

算法设计思路

两个指针的一个操作而逐步向中间合拢的过程
得到了一个由大到小的一个数组
题意输出是由小到大的一个元素的集合
下标就由大到小来进行更新就可以了

代码实现

/**2个数组
 * Note: The returned array must be malloced, assume caller calls free().
 */
#include <stdlib.h>

int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    // 分配内存来存储结果
    int* result = (int*)malloc(sizeof(int) * numsSize);
    if (result == NULL) {
        *returnSize = 0;
        return NULL; // 内存分配失败
    }

    int i = 0, j = numsSize - 1;
    int k = numsSize - 1; // 从数组末尾开始填充结果数组

    while (i <= j) {
        if (abs(nums[i]) > abs(nums[j])) {
            result[k] = nums[i] * nums[i];
            i++;
        } else {
            result[k] = nums[j] * nums[j];
            j--;
        }
        k--;
    }

    *returnSize = numsSize; // 设置返回数组的大小
    return result;          // 返回分配的数组
}
  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值