代码随想录算法训练营day01(数组理论基础, 二分查找, 移除元素)

一.数组理论基础

数组

数组是存放在连续内存空间上的相同类型数据的集合

注意:

1.数组下标都是从0开始的

2.数组的元素不能删,只能覆盖

二维数组

在C++中二维数组在地址空间上是连续的

在java中二维数组的每一行头结点的地址随机,后续结点连续

在这里插入图片描述

704.二分查找

https://leetcode.cn/problems/binary-search

注意:1.数组下标从0开始,到nums.length-1结束

2.二分查找要求无重复元素有序数组

3.“左闭右闭”和“左闭右开”的区别

1.左闭右闭,left和right可相等

 [left,right]int right = nums.length - 1while(left<=right)  
  ③right=mid-1;
class Solution {  
     public int search(int[] nums, int target) {  
         while(target < nums[0] || target > nums[nums.length-1])  
             return -1;  
         //左闭右闭  
         int left = 0, right = nums.length - 1;  
         while(left<=right){  
             int i=(left+right)/2;  
             if(nums[i]<target)//target比中间数大  
                 left=i+1;  
             else if(nums[i]>target)target比中间数小  
                 right=i-1;  
             else  
                 return i;  
         }  
         return -1;  
     }  
  }

2.左闭右开,则left和right不可相等

[left,right)  
  ①int right = nums.length  
  ②while(left<right)  
  ③right=mid;
class Solution {  
     public int search(int[] nums, int target) {  
         while(target < nums[0] || target > nums[nums.length-1])  
             return -1;  
         //左闭右开  
         int left = 0, right = nums.length ;  
         while(left<right){  
             int i=(left+right)/2;  
             if(nums[i]<target)//target比中间数大  
                 left=i+1;  
             else if(nums[i]>target)target比中间数小  
                 right=i;  
             else  
                 return i;  
         }  
         return -1;  
     }  
  }

35.搜索插入位置

https://leetcode.cn/problems/search-insert-position

注意点:1.时间复杂度要求为O(logn),因此需要使用二分查找

2.在数组中,未找到时,返回left or right+1

3.target不在范围内的情况可以不用考虑

1.左闭右闭

//思路:二分查找,找到则输出下标,找不到则输出left-1

  class Solution {  
     public int searchInsert(int[] nums, int target) {  
         //target不在范围  
         if(target <= nums[0])  
             return 0;  
         if(target > nums[nums.length -1])  
             return nums.length;  
         int left=0,right=nums.length -1;  
         while(left <= right){  
             int mid= (left+right)/2;  
             if(nums[mid]<target)  
                left=mid+1;   
             else if(nums[mid]>target)  
                 right=mid-1;  
             else  
                 return mid;  
         }  
          return left;  
     }  
  }

2.左闭右开

class Solution {  
     public int searchInsert(int[] nums, int target) {  
         int left=0,right=nums.length ;  
         while(left < right){  
             int mid= (left+right)/2;  
             if(nums[mid]<target)  
                left=mid+1;   
             else if(nums[mid]>target)  
                 right=mid;  
             else  
                 return mid;  
         }  
          return left;  
     }  
  }

27. 移除元素

https://leetcode.cn/problems/remove-element

注意点:1.数组元素不能删除,只能覆盖(循环覆盖,即自带一层循环)

2.数组移除元素=覆盖掉目标元素+数组缩短被移除元素的个数

1.暴力解,两次循环

  // 时间复杂度:O(n^2)  
  // 空间复杂度:O(1)  
  class Solution {  
     public int removeElement(int[] nums, int val) {  
         int length =nums.length;   
         for(int i=0;i<length;i++){  
             if(nums[i]==val){  
                for(int j=i+1;j<length;j++)  
                     nums[j-1]=nums[j];  
                  i--;  
                  length--;  
             }  
         }  
         return length;          
     }  
  }

2.快慢指针法

在这里插入图片描述

基础思想(自己根据动图想的):

①快慢指针位置相同时,一起移动,慢指针遇到val即停;

②快指针继续向前,当快慢指针位置不同时,快指针往回覆盖;快指针遇到val时,返回到慢指针位置

进阶思想(根据书上算法分析的):

①仅快指针遍历,当快指针不等于val时,给慢指针赋值

②是“虚拟数组法”的进阶。只不过在“虚拟数组法”中,当指针不等于val时,给另外一个数组赋值,而该算法赋值给同一个数组,从而实现了所谓的“覆盖”

  
  class Solution {  
     public int removeElement(int[] nums, int val) {  
         int length =nums.length;   
         int slowIndex = 0;  
         for(int fastIndex = 0 ;fastIndex < length;fastIndex++){  
             if(nums[fastIndex]!=val){//如果快指针位置的值和val不同,快指针给慢指针位置赋值  
                 nums[slowIndex]=nums[fastIndex];  
                 slowIndex++;  
             }  
         }  
         return slowIndex;  
     }  
  }

3.相向双指针方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值