Day1:代码随想录算法训练营|704.二分查找、27.移除元素

1,718 阅读3分钟

一.数组理论基础

看过代码随想录整理,我觉得重点有这些

1.数组在内存中的存储方式?

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

2.数组与链表的区别

数组:访问快,增删慢。 链表:访问慢,增删快。

原因1:数组可以通过下标索引的方式进行快速访问。但是由于数组的内存地址是连续的,在增删元素的时候就需要移动其他的元素,来达到增删的效果。

原因2:链表中的内存地址不一定是连续的,要查找链表中的一个元素,需要从第一个元素开始访问,访问效率低。 链表由节点构成,每个节点由一个数据域和一个指针域(存放下一个元素的地址)构成,增删只需要改变地址就可以了。

参考文章:t.csdn.cn/a4S6e (数组与链表区别)

3.数组的元素能删除吗?

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

4.二维数组的内存空间地址是连续的么?

不同的编程语言内存管理不一样,c++中二维数组内存空间是连续分布的。Java的没有指针,同时也不对程序猿暴露出元素的地址,寻址操作完全交给JVM,不是连续的。

参考文章: programmercarl.com/%E6%95%B0%E…(数组理论基础)

二. 数组相应题目练习

704.二分查找

对应题目链接:leetcode.cn/problems/bi… 之前已经做过这的题了,是一道原汁原味的二分查找,要分析边界的每个含义。

二分法适应场景:数组有序,数组元素唯一

二分查找注意事项以及重难点:边界处理

二分法常见两种写法:左闭右闭,左闭右开

二分查找复杂度:时间复杂度O(logn) 空间复杂度:O(1)

二分法自我理解与困难分析

算法:一个有序数组,定义左右两个指针,比较目标元素和中间元素的大小,不断缩小左右指针的范围,找到目标数。 刚开始的时候我对于边界定义不是很明确,看完代码随想录后对于边界定义进行明确。

二分法左闭右闭代码及解析

//左闭右闭
class Solution {

public int search(int[] nums, int target) {
int left=0;

int right=nums.length-1;

while(left<=right){//举个例子:[1,1] 1<=1是个合法区间,满足左闭右闭

int mid=left+(right-left)/2;//left,right过大的话超出nums.length就不能执行/2操作了,两个int有时相加会越界

if(nums[mid]<target){//这时候需要更新右区间的左边界

left=mid+1;//确定当前中间的数已经小于target了,所以一定不包含中间那个数

}else if(nums[mid]>target){//更新左区间的右边界

right=mid-1;//确定当前中间的数已经大于target了,所以一定不包含中间那个数

}else{

return mid;

}

}

return -1;

}

}

二分法左闭右开代码及解析

class Solution {

public int search(int[] nums, int target) {

//左闭右开

int left=0;

int right=nums.length;//由于是左闭右开

while(left<right){

int mid=left+(right-left)/2;//防止溢出

if(nums[mid]>target){

right=mid;//更新左区间的右边界,又由于是左闭右开

}else if(nums[mid]<target){

left=mid+1;//更新右区间左边界

}else{

return mid;

}

}

return -1;


}

}

对应文章链接programmercarl.com/0704.%E4%BA…

对应视频讲解:www.bilibili.com/video/BV1fA…

27.移除元素

对应的题目链接:leetcode.cn/problems/re…

复杂度:时间复杂度O(n) 空间复杂度:O(1)

移除元素自我理解与困难分析一

算法:双指针,快指针从头到尾遍历数组,要是遇到不等于val的就赋给慢指针,最后返回慢指针。这里边慢指针就是相当于一个新数组。 难点:需要在原数组进行修改

移除元素代码与解析

class Solution {

public int removeElement(int[] nums, int val) {

int j=0;//慢指针

for(int i=0;i<nums.length;i++){//快指针

if(nums[i]!=val){

nums[j]=nums[i];

j++;

}

}

return j;

}

}

解法2 暴力解法

算法:两层for循环,第一层for去遍历数组,要是遇到了值为val的数组,第二层for循环i后面的元素往前覆盖,要注意数组的长度要对应相减,从而得到一个新数组。

时间复杂度o(n^2)

移除元素暴力解法代码分析

class Solution {

public int removeElement(int[] nums, int val) {

int size=nums.length;

for(int i=0;i<size;i++){

if(nums[i]==val){

for(int j=i+1;j<size;j++){

nums[j-1]=nums[j];

}

i--;

size--;

}

}

return size;

}

}

对应文章链接programmercarl.com/0027.%E7%A7… 对应视频链接:

视频讲解:www.bilibili.com/video/BV1fA…

最后的鸡汤:希望自己坚持下去

如果有哪里不正确的地方希望大佬们评论指正哦!!!!!