leetcode 704.二分查找

题目

704.二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

解题思路

1、先获取数组的中间数
2、中间数和目标值进行比较
中间数 == 目标值,return中间数下标
中间数 > 目标值,取数组的前一半,中间数变成新数组右边最后一个元素 [left, ... , mid]
中间数 < 目标值,取数组的后一半,中间数变成新数组左边第一个元素 [mid, ... ,right]
3、循环1和2操作直到获取到目标值,若找不到则返回-1
获取新数组的中间数 -> 中间数和目标值比较 -> 找到返目标值回下标,找不到返回-1

实现代码

from typing import List
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            if nums[mid] > target:
                right = mid -1
            if nums[mid] < target:
                left = mid + 1
        return -1
    
test = Solution()
nums = [-1,0,3,5,9,12]
target = 9
print(test.search(nums, target))

本题对自己的难点

有大概的解题思路,但是代码实现写不出来
1、怎么取中间数的下标
原思路:中间数下标 = len(arr) // 2 即数组长度除以2的商 --当数组长度为奇数时,正好取到中间数
问题1:数组长度为偶数时,中间数取哪个? --如果同样按以上计算方法,是取两个数中前一个小的
问题2:第一次获取到中间数后,中间数和目标值进行比较,如果不相等,需要取原数组的一半(前一半或后一半),中间数会作为新数组的一个边界值(右边界值或左边界值)
开始第二次获取中间数下标,再按以上计算方法,中间数下标 len(arr) // 2 // 2 一直在变化,不知道代码怎么表示 。。。
2、循环的条件没有想清楚
3、以上两个问题半小时内搞不定,直接看题解
(1)取中间数的方法
left = 0
right = len(nums) - 1
mid = (left + right) // 2
(2)循环的条件
while left <= right

其他问题

本地VSCode调试报错:
def search(self, nums: List[int], target: int) -> int:
NameError: name 'List' is not defined
解决办法:
python文件头引入typing模块 from typing import List
问题扩展:
(1)import typing后可以直接使用的数据类型
int、long、float、str、bool
(2)需要from typing import xxx的数据类型
List列表、Tuple元祖、Dict字典、Set集合 from typing import List,Tuple,Dict,Set
Iterable可迭代类型、Iterator迭代器 from typing import Iterable,Iterator
Generator生成器类型 from typing import Generator

leetcode 27.移除元素

题目

27.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

解题思路

主要思想:
不要想着删除数组中元素值和val相等的元素,而是留下不等于val的元素

实现过程:
在同一个数组上使用双指针操作
使用快慢双指针更新 新数组
快指针获取新数组的元素值
慢指针获取新数组的位置
当快指针获取的元素值≠val值时,就是新数组需要留下的值

实现代码

from typing import List
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        fast = 0
        slow = 0
        while fast < len(nums):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow
    
test = Solution()
nums = [1, 2, 3, 4, 3, 5]
val = 3
print(test.removeElement(nums, val))  

本题对自己的难点

1、解题思路
(1)看完题目首先想到通过while循环和remove函数删除值为val的元素,但直接用函数太简单了,题目应该是要实现remove函数的过程

arr = [1,2,2,3]
i = 0
while i < len(arr):
    i += 1
    arr.remove(2)
print(arr)
print(len(arr))

(2)看完题解代码后,发现可以从另一个角度想问题,不是去删除元素,而是留下要的元素
2、只看题解代码没看卡哥视频前,想不通为什么最后一行return慢指针返回的是新数组长度

posted on 2024-04-04 12:44  小鹿BAMBI  阅读(43)  评论(0编辑  收藏  举报