目的
- 理解數組的 基本概念 及其 操作方式;
- 理解
二維數組
的基本概念,熟悉二維數組的使用; - 瞭解
字符串的概念
以及字符串所具有的不同特性; - 理解字符串匹配中的
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最大和最小的字符串的公共部分。