今日学习的文章链接如下:
704. 二分查找
自己看到题目的第一想法
拿到题目首先想办法,一个是从头到尾遍历(这肯定很慢),还有一种办法就是二分法。想了半天决定应该先排序,后定睛一看,发现自己漏掉题目中的已知条件“按升序排列”……想到了解决办法,但不知道如何用编程语言表达,想用Java解,但是Java太久没用忘差不多了……
遇到的主要问题
脑海中有框架的感觉了,不知道如何循环起来;
java输出语句、if语句、函数得看一眼;
不知道怎么表示每次区间变化之后的中间量;
看完代码随想录之后的想法
于是看解析,由于解析的代码是用c++写的,我没接触过c++,误以为是Java,看了半天没看懂,也看不进去。中途放弃了大概五六个小时去摆烂了,又处理了一下和男友之间的事情,直到晚上十点半才重新回到书桌前看代码,看的是后面c的代码,一下豁然开朗了。
一些关键点
用left和right表示区间;
用middle表示区间的中间值,middle = (left + right)/2(这里我又犯了一个错误,算两个数的中间值我用一种特别麻烦的表示方法,其实就是左加右除以2这么简单的表示);
用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
重要知识点
数组为有序数组,同时题目还强调数组中无重复元素——可以考虑二分法
Java四种输出语句
System.out.println(1111);//换行打印
System.out.print(1111);//不换行打印
System.out.write(2222);//字节输出
System.out.printf("%+8.3f\n", 3.14);//按格式输出
Java函数定义
https://blog.csdn.net/HoHiuChing/article/details/77480471
反思
看题没认真仔细看,浮皮潦草就扫过去了,导致忽略已知条件,影响做题。下次看题目要一个字一个字看,可以读两遍以上再开始想做题的办法。
中途遇到Java语言和c++语言的一点小挑战就以为自己遇到了多难多难的问题,严重高估问题的难度、严重低估自己对问题的理解度,导致放弃。并且假期在家自制力较差,拿起手机就放不下。需要管控一下学习期间手机的滥用。
写代码不仔细,小问题频出。下次写完之后仔细再回看一遍。