今天开始进行为期两个月的代码随想录刷题,并在此更新我的做题记录,也期望博客能成为我记录学习的一个好习惯。
第一章为数组,也叫做顺序表,它的最大特点就是顺序存储且地址连续。
第一道题为二分查找,该方法只适用于数组中元素的大小有序的情况下,基本原理大概为:当给定一个数组以及一个所需要查找的数字时,先取数组最中间的元素即下标为1/2这样的时候,先与之对比。以升序为例,如果中间的元素比所查找的元素大,那么就将查找区间转为该下标的右边部分,反之则查找左边部分。
谈谈实现,由于我是算法菜鸟,因此我并不报仅靠自己就可以实现算法的期望,正如我常说的,我是一个庸才,但我仍然想重复天才已给出的财富,在此之上不断重复以期望找寻自己的创新。扯远了,我们需要一前一后两个指针,这样才可以方便找到数组中间的位置,在这里还要注意边界问题。go语言版本如下:
func search(nums []int,target int) int {
left:=0 //左边界
right:=len(nums) -1 //右边界
for left <= right {
mid:=left + (right - left)>>1
if target == nums[mid] {
return mid
}else if target > nums[mid] {
left = mid + 1
}else{
right = mid -1
}
}
return -1 //这里为异常情况
}
python版本如下,这里仍然需要边界注意,此时为左闭右开:
def search(self,nums:List[int],target:int)-> int:
left,right=0,len(nums)
while left < right:
mid = left + (right -left) //2
if target > nums[mid]:
left = mid +1
elif target < nums[mid]:
right = mid
else:
return mid
return -1
紧接着是移除元素,我们需要对一个数组原地查找等于给定数值val的数值并原地删除最后输出不同于所查找值的数量,这里先演示暴力解法,即两个for循环,一个用以便利所有元素,并在第一层for循环中使用判断语句筛选条件后再嵌套一个for循环对元素进行重新排序,这里演示go语言的版本:
func removeElement(nums []int, val int) int {
size:=len(nums)
for i:=0;i<size;i++{
//从0开始遍历故此时一定是第一个出现的val,因此j从i+1开始来找到另外的val
if nums[i] == val{
for j:=i+1;j<size;j++{
nums[j-1] = nums[j]
}
i--
size--
}
}
return size
}
python的版本则同理:
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i = 0
l = len(nums)
while i < l:
if nums[i] == val:
for j in range(i+1,l):
nums[j-1] = nums[j]
l-=1
i-=1
i+=1
return l
这里再演示一个快慢指针法,使用python实现:
def remove(self,nums:List[int] ,val int) -> int:
slow=0
fast=0
size=len(nums)
while fast<size:
if nums[fast] != val:
nums[slow] = nums[fast]
slow+=1
fast+=1
return slow
func removeElement(nums []int, val int) int {
slow:=0
fast:=0
size:=len(nums)
for i:=0;i<size;i++{
if nums[fast] != val{
nums[slow] = nums[fast]
slow++
}
fast++
}
return slow
}
所谓快慢指针法,一快一满指针同时从起点出发,快指针先行出发,在遍历的途中,如果有不等于所查找的值的,慢指针所代表的值就与之交换并位置进一,同时快指针继续遍历,最终找到数量就是slow慢指针的值