本文全部題目和部分題解均源於LeetCode
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problemset/all/
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。node
說來也是慚愧,在大學裏就註冊了LeetCode帳號,而到如今又從新註冊了一個帳號開始刷題…
若不是最近在深刻學習人工智能,我可能不會碰它吧…哈哈python
LeetCode刷題之路
1. 兩數之和
-
題目web
給定一個整數數組
nums
和一個目標值target
,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。正則表達式你能夠假設每種輸入只會對應一個答案。可是,數組中同一個元素不能使用兩遍。算法
示例:數組
給定 nums = [2, 7, 11, 15], target = 9 由於 nums[0] + nums[1] = 2 + 7 = 9 因此返回 [0, 1]
-
解題思路
咱們把原先的數組轉爲字典,經過字典查詢加快速度。網絡
- 判斷
target
-nums[i]
是否在字典中,不在就添加 - 經過查詢到的字典的值反向獲取下標索引
- 實現代碼
def twoSum(nums, target): dic = { } n = len(nums) for i in range(n): if target - nums[i] in dic: return dic[target - nums[i]], i else: dic[nums[i]] = i
2. 兩數相加
-
題目app
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,而且它們的每一個節點只能存儲 一位 數字。svg
若是,咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。函數
您能夠假設除了數字 0 以外,這兩個數都不會以 0 開頭。
示例:輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 輸出:7 -> 0 -> 8 緣由:342 + 465 = 807
-
解題思路
經過對每個位置進行除法運算和取餘來肯定本位置的值,以及該位置是否須要進一。 -
實現代碼
-
在Pycharm上實現代碼
class ListNode: def __init__(self, val): if isinstance(val, int): self.val = val self.next = None elif isinstance(val, list): self.val = val[0] self.next = None cur = self for i in val[1:]: cur.next = ListNode(i) cur = cur.next def gatherAttrs(self): return ", ".join("{}: {}".format(k, getattr(self, k)) for k in self.__dict__.keys()) def __str__(self): return self.__class__.__name__ + " {" + "{}".format(self.gatherAttrs()) + "}" class Solution: def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: if isinstance(l1, list): l1 = ListNode(l1) l2 = ListNode(l2) head = ListNode(0) # 頭結點,無存儲,指向鏈表第一個結點 node = head # 初始化鏈表結點 s = 0 # 初始化 進一 的數 while l1 or l2: x = l1.val if l1 else 0 y = l2.val if l2 else 0 sum = x + y + s # 對每一位求和 s = sum // 10 # 求進一(其爲0或1) node.next = ListNode(sum % 10) # 取餘數,求本位結點 if l1: # 求空否,防止出現無後繼結點 l1 = l1.next if l2: # 同上 l2 = l2.next node = node.next # 更新指針 if s != 0: # 驗證最後一位相加是否需 進一 node.next = ListNode(1) return head.next # 返回頭結點的下一個結點,即鏈表的第一個結點 if __name__ == '__main__': test = Solution() print(test.addTwoNumbers([1, 3], [2, 1, 3]))
-
在LeetCode上實現代碼
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: head = ListNode(0) #頭結點,無存儲,指向鏈表第一個結點 node = head #初始化鏈表結點 s = 0 #初始化 進一 的數 while l1 or l2: x = l1.val if l1 else 0 y = l2.val if l2 else 0 sum = x + y + s # 對每一位求和 s = sum // 10 # 求進一(其爲0或1) node.next = ListNode(sum % 10) # 取餘數,求本位結點 if l1: # 求空否,防止出現無後繼結點 l1 = l1.next if l2: # 同上 l2 = l2.next node = node.next # 更新指針 if s != 0: # 驗證最後一位相加是否需 進一 node.next = ListNode(1) return head.next # 返回頭結點的下一個結點,即鏈表的第一個結點
3. 無重複字符的最長子串
-
題目
給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。示例 1:
輸入: "abcabcbb" 輸出: 3 解釋: 由於無重複字符的最長子串是 "abc", 因此其長度爲3。
示例 2:
輸入: "bbbbb" 輸出: 1 解釋: 由於無重複字符的最長子串是 "b", 因此其長度爲 1。
示例 3:
輸入: "pwwkew" 輸出: 3 解釋: 由於無重複字符的最長子串是 "wke", 因此其長度爲 3。請注意,你的答案必 須是子串的長度,"pwke" 是一 個子序列,不是子串。
-
解題思路
本題主要採起遍歷的方式來記錄最長的字符串。
- 對字符串進行遍歷,若不重複,存入暫存的字符串變量;
- 遇到重複,則找到重複字符出現的第一個位置,保存其後面的字符串;
- 比較當前字符串和記錄的最長字符串,若是當前更長,則進行替換。
- 實現代碼
def lengthOfLongestSubstring(str): max_str = '' # 保存最大字符串長度 ele_str = '' # 暫存字符串 for element in str: # 對字符串進行遍歷,若是不重複則存入暫存的字符串變量 if element not in ele_str: ele_str += element # 遇到重複,則找到重複字符出現的第一個位置,保存其後面的字符串 else: ele_str = ele_str[ele_str.index(element) + 1:] ele_str += element # 若是當前字符串更長,則進行替換 if len(ele_str) > len(max_str): max_str = ele_str return len(max_str)
4. 尋找兩個正序數組的中位數
-
題目
給定兩個大小爲m
和n
的正序(從小到大)數組nums1
和nums2
。請你找出這兩個正序數組的中位數,而且要求算法的時間複雜度爲
O(log(m + n))
。你能夠假設
nums1
和nums2
不會同時爲空。 -
解題思路
咱們能夠將兩個數組合併成一個數組,排序後找到中位數(1) 用Python數組的
extend()
函數,將第二個數組的元素添加到第一個數組中nums1.extend(nums2)
(2) 對當前數組進行排序nums1.sort()
(3) 判斷中位數下標,咱們設數組長度爲l
,l = len(nums1)
,中位數設爲res
- 若爲數組長度爲奇數,則中位數爲
nums1[l//2]
- 若爲數組長度爲偶數,則中位數爲
(nums1[l // 2 - 1] + nums1[l // 2]) / 2
- 若爲數組長度爲奇數,則中位數爲
-
實現代碼
def findMedianSortedArrays(num1, num2): num1.extend(num2) num1.sort() l = len(num1) if l % 2 == 1: res = num1[l // 2] else: res = (num1[l // 2 - 1] + num1[l // 2]) / 2 return res
5. 最長迴文子串
-
題目
給定一個字符串s
,找到s
中最長的迴文子串。你能夠假設s
的最大長度爲 1000。示例 1:
輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。
示例 2:
輸入: "cbbd" 輸出: "bb"
-
解題思路
從最長字符串開始比較,好比說字符串長是5,那就先把原串取反進行比較,若是不相等,則縮短長度到4,分別比較,以此類推。 -
實現代碼
def longestPalindrome(s): for l in range(len(s), -1, -1): for i in range(0, len(s) - l + 1): res_str = s[i:l + i] if res_str == res_str[::-1]: return res_str
6. Z字形變換
-
題目
將一個給定字符串根據給定的行數,以從上往下、從左到右進行Z
字形排列。好比輸入字符串爲
"LEETCODEISHIRING"
行數爲 3 時,排列以下:L C I R E T O E S I I G E D H N
以後,你的輸出須要從左往右逐行讀取,產生出一個新的字符串,好比:
"LCIRETOESIIGEDHN"
。請你實現這個將字符串進行指定行數變換的函數:
string convert(string s, int numRows);
示例 1:
輸入: s = "LEETCODEISHIRING", numRows = 3 輸出: "LCIRETOESIIGEDHN"
示例 2:
輸入: s = "LEETCODEISHIRING", numRows = 4 輸出: "LDREOEIIECIHNTSG" 解釋: L D R E O E I I E C I H N T S G
-
解題思路
咱們先把L C I R E T O E S I I G E D H N
寫成下面這個樣子,也就是
V
型的,比題目說的N
型好理解
能夠想象用手捏着最後一個字符,往右拉了一下:L C I R E T O E S I I G E D H N
實際上就是,
對列來講,一直往右走,
對行來講,碰到邊界就改變方向 -
實現代碼
def convert(s: str, numRows: int) -> str: if numRows <= 1: return s array = [s for a in range(numRows)] # ['LEETCODEISHIRING', 'LEETCODEISHIRING', 'LEETCODEISHIRING'] ans = [list() for b in range(numRows)] # [[], [], []] i, direction = 0, 1 res = '' for j in range(0, len(s)): ans[i].append(array[i][j]) i += direction if i == 0 or i == numRows - 1: direction *= -1 res = list() for element in ans: for k in element: res.append(k)
7. 整數反轉
-
題目
給出一個 32 位的有符號整數,你須要將這個整數中每位上的數字進行反轉。示例 1:
輸入: 123 輸出: 321
示例 2:
輸入: -123 輸出: -321
示例 3:
輸入: 120 輸出: 21
注意:
假設咱們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−231, 231 − 1]。請根據這個假設,若是反轉後整數溢出那麼就返回 0。
-
解題思路
- 先將整數轉換爲字符串;
- 判斷字符串的第一個元素是否爲
‘-’
,若是是,加‘-’
並反轉字符串,若是不是則直接反轉字符串; - 判斷反轉後的字符串是否在 -231~231-1 範圍內,若不在返回0。
-
實現代碼
def reverse_(x): s = str(x) if s[0] == '-': x = int('-' + s[1:][::-1]) else: x = int(s[::-1]) if (-2 ** 31) < x < (2 ** 31 - 1): return x else: return 0
8. 字符串轉換整數(atoi)
-
題目
請你來實現一個 atoi 函數,使其能將字符串轉換成整數。首先,該函數會根據須要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。接下來的轉化規則以下:
● 若是第一個非空字符爲正或者負號時,則將該符號與以後面儘量多的連續數字字符組合起來,造成一個有符號整數。
● 假如第一個非空字符是數字,則直接將其與以後連續的數字字符組合起來,造成一個整數。
● 該字符串在有效的整數部分以後也可能會存在多餘的字符,那麼這些字符能夠被忽略,它們對函數不該該形成影響。注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不須要進行轉換,即沒法進行有效轉換。
在任何狀況下,若函數不能進行有效的轉換時,請返回 0 。
提示:
本題中的空白字符只包括空格字符 ’ ’ 。
假設咱們的環境只能存儲 32 位大小的有符號整數,那麼其數值範圍爲 [−231, 231 − 1]。若是數值超過這個範圍,請返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。示例 1:
輸入: "42" 輸出: 42
示例 2:
輸入: " -42" 輸出: -42 解釋: 第一個非空白字符爲 '-', 它是一個負號。 咱們儘量將負號與後面全部連續出現的數字 組合起來,最後獲得 -42 。
示例 3:
輸入: "4193 with words" 輸出: 4193 解釋: 轉換截止於數字 '3' , 由於它的下一個字符不爲數字。
示例 4:
輸入: "words and 987" 輸出: 0 解釋: 第一個非空字符是 'w', 但它不是 數字或正、負號。所以沒法執行有效的轉換。
示例 5:
輸入: "-91283472332" 輸出: -2147483648 解釋: 數字 "-91283472332" 超過 32 位有符號 整數範圍。 所以返回 INT_MIN。
-
解題思路
本題採用正則表達式來匹配關鍵字,從而獲得本身想要的結果。 -
實現代碼
import re def myAtoi(str): INT_MIN = -2 ** 31 INT_NAX = 2 ** 31 - 1 str = str.lstrip() num = 0 str_re = re.compile('^[\+\-]?\d+') num_str = str_re.findall(str) for i in num_str: num = int(''.join(i)) if num > INT_NAX: num = INT_NAX elif num < INT_MIN: num = INT_MIN return num
9. 迴文數
-
題目
判斷一個整數是不是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是同樣的整數。示例 1:
輸入: 121 輸出: true
示例 2:
輸入: -121 輸出: false 解釋: 從左向右讀, 爲 -121 。 從右向左讀, 爲 121- 。所以它不是一個迴文數。
示例 3:
輸入: 10 輸出: false 解釋: 從右向左讀, 爲 01 。所以它不是一個迴文數。
-
解題思路
轉爲字符串,再進行判斷 -
實現代碼
def isPalindrome(x: int): s = str(x) # if s == s[::-1]: # return True # else: # return False return s[::-1] == s
10. 正則表達式匹配
-
題目
給你一個字符串s
和一個字符規律p
,請你來實現一個支持'.'
和'*'
的正則表達式匹配。'.' 匹配任意單個字符 '*' 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串
s
的,而不是部分字符串。說明:
●
s
可能爲空,且只包含從a-z
的小寫字母。
●p
可能爲空,且只包含從a-z
的小寫字母,以及字符.
和*
。示例 1:
輸入: s = "aa" p = "a" 輸出: false 解釋: "a" 沒法匹配 "aa" 整個字符串。
示例 2:
輸入: s = "aa" p = "a*" 輸出: true 解釋: 由於 '*' 表明能夠匹配零個或多個前面的 那一個元素, 在這裏前面的元素就是 'a'。 所以,字符串 "aa" 可被視爲 'a' 重複了一次。
示例 3:
輸入: s = "ab" p = ".*" 輸出: true 解釋: ".*" 表示可匹配零個或多個('*') 任意字符('.')。
示例 4:
輸入: s = "aab" p = "c*a*b" 輸出: true 解釋: 由於 '*' 表示零個或多個,這裏 'c' 爲 0 個, 'a' 被重複一次。所以能夠匹配字符串 "aab"。
示例 5:
輸入: s = "mississippi" p = "mis*is*p*." 輸出: false
-
解題思路
這裏參考的他人的解題思路,不得不說,我怕是長了個假腦子,
@lru_cache(None)裝飾符,實現記憶化搜索,等價於Top-Down動態規劃,不懂其用法的可自行百度… -
實現代碼
class Solution: @lru_cache(None) def isMatch(self, s: str, p: str) -> bool: if not p: return not s # 結束條件 first_match = (len(s) > 0) and p[0] in { s[0], '.'} # 先處理 `*` if len(p) >=2 and p[1] == '*': # 匹配0個 | 多個 return self.isMatch(s, p[2:]) or (first_match and self.isMatch(s[1:], p)) # 處理 `.` ,匹配一個 return first_match and self.isMatch(s[1:], p[1:])
本文分享 CSDN - MangoloD。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。