Leetcode【73、74】

问题描述:【Array】73. Set Matrix Zeroes
解题思路:

给一个 m*n 矩阵,将 0 所在的行和列元素都置为 0。

首先这题最重要的一点,是如何处理置 0 后,不会影响后续遍历结果。也就是要避免在某次操作中我将 a[i][j] 置 0,而之后我遍历到 a[i][j] 元素时,其原本的值丢失,导致最后数组所有元素都是 0。

方法1:空间复杂度为 O(m*n),时间复杂度为 O(m*n*max(m,n))

扫描原矩阵,将元素为 0 的下标 [i, j] 保存到数组中(最多有 m* n 个 0)。遍历数组,将原矩阵的行 i 和列 j 的元素置 0。

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])
        zeros = []  # 保存 0 元素下标 (i, j)
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    zeros.append((i,j))
        for zero in zeros:  # 遍历数组
            for j in range(n):  # 所在行 zero[0] 置 0
                matrix[zero[0]][j] = 0
            for i in range(m):  # 所在列 zero[1] 置 0
                matrix[i][zero[1]] = 0

方法2:空间复杂度为 O(m+n),时间复杂度为 O(m*n)

比起方法 1,可以将 0 所在的行 i 和 列 j 分别记录到两个数组中。然后,分别遍历这两个数组,将行和列分别置 0。这样空间复杂度为 O(m+n),时间复杂度为 O(m*n)。

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])
        row, col = [], []  # 分别记录原数组 0 元素的行跟列
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    row.append(i)
                    col.append(j)
        for r in row:  # 所在行 r 置 0
            for j in range(n):
                matrix[r][j] = 0
        for c in col:  # 所在行 c 置 0
            for i in range(m):
                matrix[i][c] = 0

方法3:空间复杂度为 O(1),时间复杂度为 O(m*n)

如何不开辟空间也可以完成置 0 操作呢?就要保证原矩阵后续的 0 不受前面元素 0 的影响。因此,可以在遍历原矩阵遇到一个 0 时,将该 0 所在的行和列、除 0 以外的其他元素都置为一个特殊值(如 float("inf") 或者 float("-inf"))。然后,再操作一次原数组,将所有特殊值置为 0 即可。因为是在原数组上操作的,空间复杂度为 O(1)。

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    for col in range(n):
                        if matrix[i][col] != 0:  # 除了 0 以外的其他元素都置为特殊值
                            matrix[i][col] = float("inf")
                    for row in range(m):  # 除了 0 以外的其他元素都置为特殊值
                        if matrix[row][j] != 0:
                            matrix[row][j] = float("inf")
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == float("inf"):  # 将特殊值置为 0
                    matrix[i][j] = 0

问题描述:【Array、Binary Search】74. Search a 2D Matrix
解题思路:

这道题是给一个 m*n 的矩阵,矩阵的行和列的元素都是升序排列,查找是否存在一个数 target。

首先,O(m*n) 的时间复杂度肯定先排除。

方法1(时间复杂度 O(m+n)):

由于矩阵的特殊性,可以先定位 target 所在的行,然后再在列中查找。定位行时,可以比较 target 与每一行的最后一个元素,如果该行的最后一个元素大于等于 target,则说明该行就是 target 所在的行。定位列时,从该行最后一个元素往前搜索,直到找到 target 所在的列。如果在搜索过程中该行元素小于 target,说明 target 不存在,返回 -1。这样,时间复杂度为 O(m+n)。

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:  # []
            return False
        m, n = len(matrix), len(matrix[0])
        if n == 0:  # [[]]
            return False
        i, j = 0, n-1
        while i < m:  # 定位 target 所在的行
            if matrix[i][-1] < target:
                i += 1
            else:
                break
        if i == m:  # target > matrix[m-1][n-1]
            return False
        while j >= 0:
            if matrix[i][j] == target:
                return True
            elif matrix[i][j] > target:
                j -= 1
            else:
                return False
        return False # target < matrxi[i][0]

方法2(时间复杂度 O(log(m*n) = O(logm + logn))):

因为如果把二维矩阵按照从左到右、从上到下进行排列,得到的序列也是升序的,因此这道题可以使用二分查找。二分查找的区间就是 A[0, m*n-1] 这 m*n 个元素。因此,此题的难点就在于中间元素索引 mid 的值 mid_val 与矩阵元素的对应关系。不难发现,mid_val = A[mid/n][mid%n]然后套用二分查找的模板比较 mid_val 与 target 即可。时间复杂度为 O(log (m*n)),即 O(logm + logn)。

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:  # []
            return False
        m, n = len(matrix), len(matrix[0])
        left, right = 0, m * n - 1
        while left <= right:
            mid = left + (right - left) // 2
            mid_val = matrix[mid//n][mid%n]
            if mid_val == target:
                return True
            elif mid_val < target:
                left = mid + 1
            else:
                right = mid - 1
        return False
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 1. Remove Duplicates from Sorted Array Description: Easy ...
    BookThief阅读 606评论 0 1
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,343评论 0 2
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,802评论 0 13
  • 1. 找出数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,...
    BookThief阅读 1,763评论 0 2
  • 出生入死。 生之徒,十有三; 死之徒,十有三; 人之生,动之死地,亦十有三。 夫何故?以其生生之厚。 盖闻善摄生者...
    一曲广陵散阅读 430评论 0 0