代码随想录算法训练营第一天_704.二分查找、27.移除元素、977.有序数组的平方

代码随想录算法训练营第一天_704.二分查找、27.移除元素、977.有序数组的平方

第一章 数组part01

数组理论基础

知识点:

  1. 数组是存放在连续内存空间上的相同类型数据的集合
  2. 数组的下标从0开始
  3. 数组内存空间的地址是连续的,不能单独删除数组中的某个元素,只能覆盖
  4. 内存地址怎么看:0x7ffee4065820与0x7ffee4065824 差了4,就是差了4个字节。因为这是一个int类型数组,所以相邻数组元素地址差4个字节。
#include <stdio.h>

void main(void)
{

    int a[2][3] = {{0,1,2},{3,4,5}};
    printf("%p %p %p \n%p %p %p"
    ,&a[0][0],&a[0][1],&a[0][2]
    ,&a[1][0],&a[1][1],&a[1][2]);
}

0x7fffffffdba0 0x7fffffffdba4 0x7fffffffdba8 
0x7fffffffdbac 0x7fffffffdbb0 0x7fffffffdbb4[1] + Done                       "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-s5ppzjrh.xmq" 1>"/tmp/Microsoft-MIEngine-Out-ljflv5n3.ue1"

704.二分查找

**思路:**两种写法:1. 左闭右闭 2. 左闭右开

**关键词:**区间定义、左区间、右边界

易错点:

  1. 是while(left<=right)还是while(left<right)【思路:根据区间定义判断是不是合法区间?】
  2. if(nums[middle]>target)时 是right=middle还是right=middle-1 【思路:判断nums[middle]是否存在于区间内,重新定义边界后是否仍是合法区间】

**总结:**边界处理规则严格按照区间定义来写,[left, right]→[left, right] [left, right]

**ps:**两个int相加可能出现越界

答案:

  1. 左闭右开

    int search(int* nums, int numsSize, int target) {
        int middle = 0;
        int left = 0;
        int right = numsSize;
        while(left < right){
            middle = (left + right) / 2;
            if(nums[middle] > target){
                right = middle;//[left right] -> [left1 right1) nums[middle] [left2 right2)
            }
            else if(nums[middle] < target){
                left = middle + 1;
            }
            else return middle;
        }
        return -1;
    }
    
  2. 左闭右闭

    int search(int* nums, int numsSize, int target) {
        int left = 0;
        int right = numsSize -1;
        int middle = 0;
        while(left<=right)
        {
            middle = (left + right)/2;
            if(target > nums[middle])
            {
                left = middle + 1;
            }
            else if(target < nums[middle])
            {
                right = middle -1;
            }
            else return middle;
        }
        return -1;
    }
    
    

27.移除元素

知识点:

思路:暴力解法O(n^2) O(1)【两个for循环】,快慢指针O(n) O(1)

总结:先把绝对会有的代码先写上去,确保一定准确,不确保就把所有可能性列出来。

答案:

  1. 暴力解法

    int removeElement(int* nums, int numsSize, int val) {
        for(int i = 0; i<numsSize;i++){
            if(nums[i] == val){
                for(int j = i; j<numsSize-1;j++){
                    nums[j] = nums[j + 1];//易错点:不能使用自增
                }
                numsSize--;
                i--;//易错点:当你在内层循环中移动元素后,你并没有更新外层循环的索引 i。这意味着如果你移除了一个元素,那么下一个元素(即原来的 nums[i+1] 现在变成了 nums[i])将被跳过而不会被检查。
            }
        }
        return numsSize;
    }
    
  2. 快慢指针

    int removeElement(int* nums, int numsSize, int val) {
        int idx_slow = 0;
        for(int idx_quick = 0; idx_quick < numsSize; idx_quick++){
            if(nums[idx_quick] != val){
                nums[idx_slow] = nums[idx_quick];
                idx_slow++;
            }
        }
        return idx_slow;
    }
    
    //要有两个数组的意识
    

ps:补充数据结构关于时间复杂度与空间复杂度的知识

977.有序数组的平方

答案:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    *returnSize = numsSize;
    int left_idx=0;
    int right_idx=numsSize-1;
    int* square_array = (int*)malloc(sizeof(int) * numsSize);

    for(int i = numsSize -1;i>-1;i--){
        if(nums[left_idx] * nums[left_idx] > nums[right_idx] * nums[right_idx]){
            square_array[i] = nums[left_idx] * nums[left_idx];
            left_idx++;
        }
        else{
            square_array[i] = nums[right_idx] * nums[right_idx];
            right_idx--;
        }
    }
    return square_array;
}
//学会读题,返回值要确定好,限制条件要确定好
今日任务

数组理论基础,704. 二分查找,27. 移除元素

详细布置
数组理论基础

文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

题目建议: 了解一下数组基础,以及数组的内存空间地址,数组也没那么简单。

704. 二分查找

题目建议: 大家今天能把 704.二分查找 彻底掌握就可以,至于 35.搜索插入位置 和 34. 在排序数组中查找元素的第一个和最后一个位置 ,如果有时间就去看一下,没时间可以先不看,二刷的时候在看。

先把 704写熟练,要熟悉 根据 左闭右开,左闭右闭 两种区间规则 写出来的二分法

题目链接:https://leetcode.cn/problems/binary-search/

文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html

视频讲解:https://www.bilibili.com/video/BV1fA4y1o715

27. 移除元素

题目建议: 暴力的解法,可以锻炼一下我们的代码实现能力,建议先把暴力写法写一遍。 双指针法 是本题的精髓,今日需要掌握,至于拓展题目可以先不看。

题目链接:https://leetcode.cn/problems/remove-element/

文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html

视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP

977.有序数组的平方

题目建议: 本题关键在于理解双指针思想

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/

文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html

视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值