Leetcode学习之路-day5:查找算法(中等)

本系列博客记录学习图解算法数据结构(链接:力扣

1.剑指 Offer 04. 二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

我一开始想通过对角线来缩小查找范围,但是发现只适合N*N的方阵,N*M我想了半天都没想明白。看了答案解析(https://leetcode.cn/leetbook/read/illustration-of-algorithm/5vl81e/),绝了。

根据方阵的特点,每个元素都比它上面的大,比它右边的小。由此可以从左下角开始比较,比目标大就往上走,比目标小就往右走,直到找到或者到方阵边界为止。

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        i, j = len(matrix)-1, 0
        while i>=0 and j <= len(matrix[0])-1:
            if matrix[i][j] > target:
                i -= 1
            elif matrix[i][j] < target:
                j += 1
            else:
                return True
        return False

2.

剑指 Offer 11. 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。  

根据旋转数组的特征,从两头同时开始往中间遍历,如果违反升序规则即找到最小值。

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if len(numbers) == 1:
            return numbers[0]
        i, j = 0, len(numbers)-1
        while i < j:
            if numbers[i] <= numbers[i+1]:
                i += 1
            else:
                return numbers[i+1]
            if numbers[j] >= numbers[j-1]:
                j -= 1
            else:
                return numbers[j]
        return numbers[0]

参考解析,还是应该继续使用二分法来查找。利用中间点与右边界的比较来寻找旋转点:

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if len(numbers) == 1:
            return numbers[0]
        i, j = 0, len(numbers)-1
        while i < j:
            m = (i+j)//2
            if numbers[m] < numbers[j]: j = m
            elif numbers[m] > numbers[j]: i = m + 1
            else: j -= 1
        return numbers[i]

3.

剑指 Offer 50. 第一个只出现一次的字符

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

用字典就可以了:

class Solution:
    def firstUniqChar(self, s: str) -> str:
        if not s:
            return " "
        dic = {}
        for c in s:
            if c not in dic:
                dic[c] = True
            else:
                dic[c] = False
        for c in s:
            if dic[c]:
                return c
        return " "

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值