《代码随想录》Day1: Intro + 数组理论基础 + 704. 二分查找 + 27. 移除元素

《代码随想录》Day 1

0. Introduction

可用工具

  • 数据结构可视化https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

1. 数组理论基础

例:字符数组

  1. 数组是存放在连续内存空间上的相同类型数据的集合,因为数组内存空间的地址是连续的,所以某一元素变动时,其他元素的内存空间地址可能也会变化
  2. 数组可以通过下标索引的方式获取到下标对应的数据,数组的下标从0开始
  3. 数组的元素不能删除,只能覆盖

2. Q704. 二分查找

题目描述:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1

  • 由于该数组是有序数组,并且数组中无重复元素,所以可用二分法更快筛查数组中target值

二分法第一种写法(左闭右闭)

每次用比较范围 [left, right] 的中点 mid 和target进行比较,若mid < target, 则更新比较范围为右半部分,left= mid+1

class Solution:
    def search(self, nums: List[int], target: int) -> int:
    	#定义target在左闭右闭区间内,保证边界的数也能被选上,且保证left=right的情况也能被讨论
    	left = 0
    	right = len(nums)-1
    	while left <= right: #用<=,保证left=right的情况也能被讨论
    		mid = left + (right-left)//2 #不用(right+left)//2是防止左右的值过大溢出
    		if mid == target:
    			return mid
    		elif mid < target:  #则搜索右半边
    			left = mid + 1
   			elif mid > target: #则搜索左半边
   				right = mid -1
		else: #没找到目标值
			return -1	

二分法第二种写法(左闭右开)

若将搜索区间定义为左闭右开区间,则
- while条件会变为while left < right (不会等于了)
- mid > target 时,更新 right 为 mid

class Solution:
    def search(self, nums: List[int], target: int) -> int:
    	#定义target在左闭右开区间内
    	left = 0
    	right = len(nums) #因右为开区间
    	while left < right: #用<,因left=right在[left,right)中无意义
    		mid = left + (right-left)//2 #不用(right+left)//2是防止左右的值过大溢出
    		if mid == target:
    			return mid
    		elif mid < target:  #则搜索右半边
    			left = mid + 1
   			elif mid > target: #则搜索左半边
   				right = mid 
		else: #没找到目标值
			return -1	

3. Q27. 移除元素

给定数组 nums 和一个值 val,需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度,元素的顺序可以改变。且不需要考虑数组中超出新长度后面的元素。

  • 但数组的特点是不能删除,只能覆盖

暴力解法

两层while循环,第一层循环遍历数组中所有元素,若搜寻到相同元素,则第二个循环来更新数组,且需要将搜索的 i 也向前移动一位,搜索范围也往前走一位

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
    	n = len(nums) 
        i = 0
        while i <n :
            if nums[i] == val: #若搜索到匹配元素
                j = i+1
                while j < n: #将数组整体前移覆盖
                    nums[j-1] = nums[j]
                    j += 1
                i -= 1 #i需要往前一位,因为i及以后的数值都向前移动了一位
                n -= 1 #此时数组的大小也减少一位
            i += 1
        return n

双指针法

分为快慢指针,快指针a用来遍历数组中每一个数,若val != nums[a],则把该数拷贝到慢指针b所指的位置,随后快慢指针同时往后移一位,这样就保证了慢指针指到的所有数都为想要的数

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        a = 0
        b = 0
        while a < len(nums):
            if nums[a] != val:
                nums[b] = nums[a]
                b += 1  #b只有搜索到不等于val的数时才+1,所以在循环里加
            a += 1 #a每次都要+1,所以在循环外加
        return b
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值