leetcode - 數組和字符串

目的

  • 理解數組的 基本概念 及其 操作方式;
  • 理解 二維數組 的基本概念,熟悉二維數組的使用;
  • 瞭解 字符串的概念以及字符串所具有的不同特性;
  • 理解字符串匹配中的KMP 算法
  • 能夠運用 雙指針 解決實際問題。

題目

1) 尋找數組的中心索引

定義: 數組中心索引的左側所有元素相加的和等於右側所有元素相加的和。(如果數組不存在中心索引,那麼我們應該返回 -1。如果數組有多箇中心索引,那麼我們應該返回最靠近左邊的那一個)

class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        # 計算總和
        total_cnt = 0 
        for i in range(len(nums)):
            total_cnt += nums[i]
        # 從索引1開始計算左邊的和,並用通過總和計算右邊的和
        left_cnt = 0
        for i in range(len(nums)):
            if i > 0:
                left_cnt += nums[i-1]
            right_cnt = total_cnt - nums[i] - left_cnt
            if left_cnt == right_cnt: 
                return i 
        return -1 

總結:需要注意的是,索引0 和 -1(這裏表示爲最後一個元素的索引) 也能做中心索引。題目似乎沒有說清楚麼~~~

2) 搜索插入位置

給定一個排序數組和一個目標值,在數組中找到目標值,並返回其索引。如果目標值不存在於數組中,返回它將會被按順序插入的位置。你可以假設數組中無重複元素。

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        for i in range(len(nums)):
            # 如果找到目標則返回索引, 或者大於目標則插入
            if nums[i] >= target:  
                return i 
        return len(nums)  # 否則在數組末尾追加
3) 合併區間

給出一個區間的集合,請合併所有重疊的區間。

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        res = []  # res保存了互不重疊的區間
        intervals = sorted(intervals, key=lambda x: x[0])
        for interval in intervals:
            if res == [] or interval[0] > res[-1][1]:  
                res.append(interval)
            else:
                res[-1] = [min(res[-1][0],interval[0]),max(res[-1][1],interval[1])]
        return res 

總結:取值區間判斷是否重疊有2種情況:a) 區間A和區間B是包含關係; b) 區間A和區間B含有交集 。解題思路爲:

  • 首先按區間的起始位置進行排序;
  • 如果結果數組爲空,或者當前區間的起始位置大於結果數組中最後區間的終止位置,則不合並; 否則合併結果數組的最後一個區間,合併後新的區間的取值範圍是:[min(left_A, left_B) , max(rigth_A,right_B)]。
4) 旋轉矩陣

給你一幅由 N × N 矩陣表示的圖像,其中每個像素的大小爲 4 字節。請你設計一種算法,將圖像旋轉 90 度。不佔用額外內存空間能否做到?

首先能想到的是使用額外空間的做法,首先將矩陣按行逆序,之後將每一列調整成每一行即可。

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        res = [[0 for i in range(n)] for i in range(n)]
        for i,x in enumerate(matrix[::-1]):
            for j in range(n):
                res[j][i] = x[j]
        for i in range(n):
            for j in range(n):
                matrix[i][j] = res[i][j]

旋轉方法: 順時針90°旋轉=對角線(左上-右下)翻轉+左右翻轉

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        # 對角線(左上-右下)翻轉
        for i in range(n-1):
            for j in range(i,n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
        # 左右翻轉 
        j = 0
        while j < (n-1)/2:
            for i in range(n): 
                matrix[i][j], matrix[i][n-1-j] = matrix[i][n-1-j], matrix[i][j]
            j += 1
5) 零矩陣

編寫一種算法,若M × N矩陣中某個元素爲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])
        row_idxs, column_idxs = set(), set()
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    row_idxs.add(i)
                    column_idxs.add(j)
        for i in range(m):
            if i in row_idxs:
                matrix[i] = [0]*n
            for j in range(n):
                if j in column_idxs:
                    matrix[i][j] = 0
6) 對角線遍歷

給定一個含有 M x N 個元素的矩陣(M 行,N 列),請以對角線遍歷的順序返回這個矩陣中的所有元素,對角線遍歷如下圖所示。

在這裏插入圖片描述

class Solution:
    def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:
        m, n = len(matrix), len(matrix[0])
        res = []
        for i in range(m+n-1):  #遍歷對角線(m+n-1)次
            ln = []
            for j in range(i+1):  #遍歷當前對角線的元素,橫座標+縱座標=對角線索引
                if j < m and i-j < n: # 判斷是否超出矩陣索引
                    ln.append(matrix[j][i-j])
            if i % 2 == 0:  # 如果對角線索引爲偶數,需要對當前對角線元素逆序
                ln = ln[::-1]
            res.extend(ln)
        return res
7) 最長公共前綴

編寫一個函數來查找字符串數組中的最長公共前綴。如果不存在公共前綴,返回空字符串 “”。

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if strs == [] : return ''
        res = ''
        min_str, max_str = min(strs), max(strs) #比較ASCII
        for i in range(len(min_str)):
            if min_str[i] != max_str[i]:
                return min_str[:i]
        return min_str

總結: 利用ASCII碼進行比較,找到ASCII最大和最小的字符串的公共部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章