代码随想录算法第一天| LeetCode704二分查找、LeetCode27移除元素、LeetCode977有序数组的平方
LeetCode 704 二分查找题目链接704.二分查找文档讲解代码随想录视频讲解二分查找思路与感想之前写过一遍704再写时隐约记得一些找定量左闭右闭、左闭右开区间双指针。靠自己写了个半成品。没办法了只能去看卡哥视频没想到卡哥直接一语道破我的困境循环处要不要等于号更新区间时中间索引要不要直接取middle还是middle1或者middle-1只能说卡哥太强了我等庸才也能轻松get到意思。而且对方理解自己的痛点并予以通俗易懂的讲解这感觉真是太美妙了收获1.二分查找中的区间性质决定了循环条件有无等于号实质上是源于写法是否让区间合法化2.取middle时该式子有索引越界异常的风险(虽然在本题中没有)//左闭右闭区间 class Solution { public int search(int[] nums, int target) { //初始化左边界 int left 0; //初始化右边界(右边界包含直接最大索引) int right nums.length - 1; //进入二分查找循环(循环边界处理[1,1]为合法区间所以左边界可以等于右边界) while (left right) { //每次进入查找循环都要更新中间索引此步骤存在索引超出边界的错误可能 int middle (left right) / 2; //判断target值和中间索引值的大小关系 if (target nums[middle]) { //targer值等于中间索引的值代表查询到数据返回middle索引 return middle; } else if (target nums[middle]) { //target值小于中间索引的值更新右边界(由于设定区间为左闭右闭此时由分支条件可知middle处的值不等于target所以在下一轮查询区间中右边界应为middle-1) right middle - 1; } else { //target值大于中间索引的值更新左边界(同上左边界为middle1) left middle 1; } } //查找循环结束没查询到值说明nums数组中不包含target数值返回-1 return -1; } }//左闭右开区间 class Solution { public int search(int[] nums, int target) { //初始化左边界 int left 0; //初始化右边界(由于是左闭右开区间右边界应为最大索引1即数组自身长度) int right nums.length; //进入二分查找循环(循环边界处理左闭右开区间[1,1)为非法区间因此左边界不可以等于右边界)) while (left right) { //每次进入循环更新中间索引(该步骤易引发索引越界问题) int middle (left right) / 2; //判断target值与中间索引值 if (target nums[middle]) { //target值与中间索引值相同代表查询到目标值索引返回middle return middle; } else if (target nums[middle]) { //target值小于中间索引值更新右边界(由于是左闭右开区间加上根据分支条件判断middle索引处值不等于target因此如果更新的右边界索引为middle本身达到了下一个查询区间不包含原middle的目的) right middle; } else { //target值大于中间索引值更新左边界(同上但注意左边界是闭合的因此更新左边界索引为middle1才可以达到下一个查询区间不包含原middle) left middle 1; } } //循环结束仍然未查询到target说明nums数组中根本不包含target故而返回-1 return -1; } }LeetCode 27 移除元素题目链接27.移除元素文档讲解代码随想录视频讲解移除元素思路和感想移除元素之前也做过说来惭愧即便视频卡哥简单谈了暴力思路暴力解法也没写出来主要卡在了没有深刻理解数组的覆盖操作且不知道如何实现看来自己对代码的掌握能力和思维还是太差了有很大的成长进步空间问题主要出在每次找到val时size没有自减处理这样做会使得案例中如果最后一个元素为val就会进入死循环内部i--完外部就i。起初超时了不知道哪里出错了。群里面问了录友和助手后发现了问题所在但是到现在也还没有完全理解这种处理逻辑目前的理解就是外层for循环遍历得长度正好是新数组得长度可是感觉还是差点什么得再去问问双指针解法倒是写出来了但是理解不深刻且代码有些冗余看了卡哥讲解后修改对双指针的设计以及快指针遍历内部的处理与不处理有了更深的理解慢指针大小恰为新数组长度多么的优雅的设计真好收获1.用IDEA把LeetCode上的代码进行Debug2.数组的覆盖操作3.nums[slow]优雅写法//暴力解法 class Solution { public int removeElement(int[] nums, int val) { int size nums.length; // 用size来记录新数组的长度默认与原数组长度相同 for (int i 0; i size; i) { // 第一层for循环查找值为val的索引 if (nums[i] val) { // 判断索引处的值等于val for (int j i 1; j size; j) { // 从val值元素下一个元素开始的区间数组整体左移一位进行覆盖(数组严格意义上不能删除只能覆盖因其内存存储的物理空间中是连续的所以表面上的删除其实只是对不需要元素进行了覆盖。在大多数语言的数组中实际上都是对数组进行过包装后的产物如它的size其实并非真实内存大小而是一个计数器数组增加元素就加一数组删除元素就减一与其真实内存大小无必然联系) nums[j-1] nums[j]; // 右区间数组整体左移一位 } i--; // 因为右区间数组整体左移一位所以相应的查找索引i也要左移一位配合进入下一次循环前的i其实就是再次判断此处位置的索引是否等于val避免漏判。 size--; // 由于找到了值为val的元素所以移除后长度减一(非常重要最后一个元素如果值为val没有这一步就会陷入死循环) } } return size; // 新数组的长度 } }//快慢指针 class Solution { public int removeElement(int[] nums, int val) { int slow 0; // 定义慢指针用于指向需要填入新数组元素的索引 for (int fast 0; fast nums.length; fast) { // 定义快指针用于查找新数组元素(即不等于val值的元素) if (nums[fast] ! val) { // 查找到了新数组元素作原数组更新处理 nums[slow] nums[fast]; // 将快指针指向的原数组元素更新的慢指针指向的新数组索引中同时慢指针右移准备填入下一个元素 } // 如果查找到的元素等于val那么就不处理跳过因为我们快指针的目的是为了查找不等于val的元素慢指针也因为没有新元素填入所以也不作移动 } return slow; // 此时慢指针的位置正好在新数组最右边的元素的右侧因此慢指针大小恰好为新数组大小 } }LeetCode 977 有序数组的平方题目链接977.有序数组的平方文档讲解代码随想录视频讲解有序数组的平方思路和感想或许是上次做这题的时候花的时间比较多加上前面写了两题感觉来了所以一看这道题十分钟就提交了最后的代码也与卡哥答案相差无几。开心开心开心不过再写一遍以及听了一遍讲解对于为何采用双指针解法和题目的解读有了更深的理解。小插曲JAVASE基础学太久了有些忘了连创建数组都忘了去查了一下简单复习。收获1.分析题目特点别着急写代码多看多分析class Solution { public int[] sortedSquares(int[] nums) { int left 0; // 设置左指针 int right nums.length - 1; // 设置右指针 int index nums.length - 1; // 由于原数组平方后从两边往中间遍历取到的值由大到小所以index设置为新数组右边界索引依次向左填充 int[] newNums new int[nums.length]; // 静态创建新数组已知长度和旧数组一致 while (left right) { // 左指针必须在小于等于右指针的情况下进行循环遍历(等于号不可以丢循环内的每次操作可理解为对当前符合条件索引值的处理填充如果是单纯小于号那么当左指针等于右指针时就会跳出循环停止遍历而此时它们共同指向的值就被丢弃了使得新数组缺失一个值) if (nums[left] * nums[left] nums[right] * nums[right]) { // 左指针的值平方后大于等于右指针则填充左指针的值。等于的话取谁都可以 newNums[index] nums[left] * nums[left]; // 填充 left; // 左指针加一 } else { newNums[index] nums[right] * nums[right]; // 同上 right--; // 右指针减一 } index--; // 填充新数组索引向左移动一位准备填新的值 } return newNums; // 返回结果 } }今日算法花了大概五个小时更新博客又花了一个小时。今天刚开Maven简单学了三个小时写完博客后再学两个小时吧然后上床睡觉估计需要还得两天完结。计算机这条路任重而道远吧这是我的第一篇博客一个大一迷茫什么技术也没学的双非普通学子在大二后终于开始了他的技术学习之路。行文至此我听着陈鸿宇的理想三旬歌词“就歌唱吧眼睛眯起来而热泪的崩坏只是没抵达的存在“最近在看村上的奇鸟行状录是部长篇。以后工作了是否还能像学生时代这般呢希望能在明年暑假找到一份实习不过转头想想实习之后的路又要怎么走呢都说大厂实习只是第一步。我想着自己好像还没有好好感受过大学的生活在大学谈一段健康的恋爱这种生活是我向往的但此刻却假借忙着学技术的借口将这缺口在我心中某处抛下了。往后的日子会后悔自己的决定吗像没有色彩的多崎作那样终于在日后某个人生阶段发现了那个滴着黑血的缺口正是未曾感受当下大学生活的我的缺憾。