代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素

本文讲述了作者在学习二分查找和移除元素问题时的经历,从初看题目到理解解题思路,再到编写和调试代码,以及对Java和C++的回忆与应用。作者反思了自己在审题和编程过程中的不足,如忽视已知条件、对问题难度的误判以及写代码时的粗心大意。
摘要由CSDN通过智能技术生成

今日学习的文章链接如下:

代码随想录 (programmercarl.com)

代码随想录 (programmercarl.com)

704. 二分查找

自己看到题目的第一想法

拿到题目首先想办法,一个是从头到尾遍历(这肯定很慢),还有一种办法就是二分法。想了半天决定应该先排序,后定睛一看,发现自己漏掉题目中的已知条件“按升序排列”……想到了解决办法,但不知道如何用编程语言表达,想用Java解,但是Java太久没用忘差不多了……

遇到的主要问题
  1. 脑海中有框架的感觉了,不知道如何循环起来;

  1. java输出语句、if语句、函数得看一眼;

  1. 不知道怎么表示每次区间变化之后的中间量;

看完代码随想录之后的想法

于是看解析,由于解析的代码是用c++写的,我没接触过c++,误以为是Java,看了半天没看懂,也看不进去。中途放弃了大概五六个小时去摆烂了,又处理了一下和男友之间的事情,直到晚上十点半才重新回到书桌前看代码,看的是后面c的代码,一下豁然开朗了。

一些关键点
  1. 用left和right表示区间;

  1. 用middle表示区间的中间值,middle = (left + right)/2(这里我又犯了一个错误,算两个数的中间值我用一种特别麻烦的表示方法,其实就是左加右除以2这么简单的表示);

  1. 用while循环表示重复比较的迭代的过程;

自己实现过程中遇到哪些困难

接下来自己写了一遍代码,在LeetCode上尝试,提示“超出时间限制”,将卡哥的代码与自己写的代码逐字比对。

不对比不知道一对比吓一跳,有几个地方马虎写错了。+写成了-,nums[middle]外头的nums被我丢了......改过之后顺利通过。

//左闭右闭
int search(int* nums, int numsSize, int target){
    int left, right, middle;
    left = 0;
    right = numsSize - 1;
    middle = 0;
    
    while(left <= right){
        middle = (right + left)/2;
        if(target > nums[middle]){
            left = middle + 1;
        }
        if(target < nums[middle]){
            right = middle - 1;
        }
        if(target == nums[middle]){
            return middle;
        }
    }
    return -1;
}
//左闭右开
int search(int* nums, int numsSize, int target){
    int left, right, middle;
    left = 0;
    right = numsSize;//把原来的闭区间 变成现在的开区间 改变的是右值 
    middle = 0;
    while(left < right)// 这里很妙 把区间扩大了一下 遇到{5}找5这种情况也没问题 left = 0 right = 1 
    {
        int middle = left + (right - left) / 2;// 由于整个大的改成了开区间 所以这里是这样表示中间值的 
        if(target > nums[middle]){
            left = middle + 1;
        }
        if(target < nums[middle]){
            right = middle;
        }
        if(target == nums[middle]){
            return middle;
        }
    }
    return -1;
}

27. 移除元素

自己看到题目的第一想法

c语言如何删除数组里的元素?

最开始的想法是遍历数组,找到其中num[i]值为val的元素,一位一位往前覆盖。

用的第一个测试用例通过了,但是提交失败,发现换了一个测试用例我这个代码就不好用了,因为我在一位一位往前覆盖的同时,让后面多余的几位都得0了。这个测试用例的val恰好就是0。于是修改了一下,直接修改numsize的值就可以解决这个问题了。

int removeElement(int* nums, int numsSize, int val)
{
    int k = 0;
    int i = 0;
    int j = 0;
    
    for(i = 0; i < numsSize; i++)
    {
        //printf("i = %d\n", i);
        
        if (nums[i] == val)
        {
            for(j = i; j <= numsSize - 2; j++)
            {
                nums[j] = nums[j+1];
                //printf("j = %d\n", j);
            }
            numsSize = numsSize - 1;
            i = i - 1;  
        }
    }
    return numsSize;
}

看完代码随想录之后的想法

双指针法

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组

  • 慢指针:指向更新 新数组下标的位置

int removeElement(int* nums, int numsSize, int val){
    int slow = 0;
    for(int fast = 0; fast < numsSize; fast++) {
        //若快指针位置的元素不等于要删除的元素
        if(nums[fast] != val) {
            //将其挪到慢指针指向的位置,慢指针+1
            nums[slow++] = nums[fast];
            /*这里也可以写成
            nums[slow] = nums[fast];
            slow = slow + 1;*/
        }
    }
    //最后慢指针的大小就是新的数组的大小
    return slow;
}

今日收获,学习时长3h

重要知识点
  1. 数组为有序数组,同时题目还强调数组中无重复元素——可以考虑二分法

  1. Java四种输出语句

System.out.println(1111);//换行打印
System.out.print(1111);//不换行打印
System.out.write(2222);//字节输出
System.out.printf("%+8.3f\n", 3.14);//按格式输出
  1. Java函数定义

https://blog.csdn.net/HoHiuChing/article/details/77480471

反思

看题没认真仔细看,浮皮潦草就扫过去了,导致忽略已知条件,影响做题。下次看题目要一个字一个字看,可以读两遍以上再开始想做题的办法。

中途遇到Java语言和c++语言的一点小挑战就以为自己遇到了多难多难的问题,严重高估问题的难度、严重低估自己对问题的理解度,导致放弃。并且假期在家自制力较差,拿起手机就放不下。需要管控一下学习期间手机的滥用。

写代码不仔细,小问题频出。下次写完之后仔细再回看一遍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值