Python小白 Leetcode刷題歷程 No.81-No.85 搜索旋轉(zhuǎn)排序數(shù)組Ⅱ、刪除排序鏈表中的重復元素Ⅱ玖像、刪除排序鏈表中的重復元素紫谷、柱狀圖中最大的矩形、最大矩形(有題干 有代碼 有思路)

Python小白 Leetcode刷題歷程 No.81-No.85 搜索旋轉(zhuǎn)排序數(shù)組Ⅱ捐寥、刪除排序鏈表中的重復元素Ⅱ笤昨、刪除排序鏈表中的重復元素、柱狀圖中最大的矩形握恳、最大矩形

寫在前面:

作為一個計算機院的大學生瞒窒,總覺得僅僅在學校粗略的學習計算機專業(yè)課是不夠的,尤其是假期大量的空檔期乡洼,作為一個小白根竿,實習也莫得路子,又不想白白耗費時間就珠。于是選擇了Leetcode這個平臺來刷題庫寇壳。編程我只學過基礎(chǔ)的C語言,現(xiàn)在在自學Python妻怎,所以用Python3.8刷題庫】茄祝現(xiàn)在我Python掌握的還不是很熟練,算法什么的也還沒學逼侦,就先不考慮算法上的優(yōu)化了匿辩,單純以解題為目的,復雜程度什么的以后有時間再優(yōu)化榛丢。計劃順序五個題寫一篇日志铲球,希望其他初學編程的人起到一些幫助,寫算是對自己學習歷程的一個見證了吧晰赞。

有一起刷LeetCode的可以關(guān)注我一下稼病,我會一直發(fā)LeetCode題庫Python3解法的选侨,也可以一起探討。

覺得有用的話可以點贊關(guān)注下哦然走,謝謝大家援制!
········································································································································································
題解框架:

    1.題目,難度
    2.題干,題目描述
    3.題解代碼(Python3(不是Python芍瑞,是Python3))
    4.或許有用的知識點(不一定有)
    5.解題思路
    6.優(yōu)解代碼及分析(當我發(fā)現(xiàn)有比我寫的好很多的代碼和思路我就會寫在這里)

········································································································································································

No.81.搜索旋轉(zhuǎn)排序數(shù)組Ⅱ

難度:中等
題目描述:


在這里插入圖片描述

題解代碼(Python3.8)

class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return True
            if nums[mid] == nums[left] == nums[right]:
                left += 1
                right -= 1
            elif nums[left] <= nums[mid]:
                if nums[left] <= target < nums[mid]:
                    right = mid -1
                else:
                    left = mid +1
            else:
                if nums[mid] < target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid -1
        return False

或許有用的知識點:
這道題要用到二分算法晨仑。
二分算法的mid值用‘mid = left + (right - left) // 2’比較好,這樣可以最大限度的防止溢出拆檬。

解題思路:
二分法洪己,判斷二分點,有幾種可能性:
1.直接 nums[mid] == target
2.當數(shù)組為 [1,2,1,1,1],nums[mid] == nums[left] == nums[right]竟贯,需要 left++, right --;
3.當 nums[left]<= nums[mid]码泛,說明是在左半邊的遞增區(qū)域
? a. nums[left] <=target < nums[mid],說明 target 在 left 和 mid 之間澄耍。我們令 right = mid - 1;
? b. 不在之間噪珊,我們令 left = mid + 1;
4.當 nums[mid] < nums[right],說明是在右半邊的遞增區(qū)域
? a. nums[mid] < target <= nums[right]齐莲,說明 target 在 mid 和 right 之間痢站,我們令 left = mid + 1
? b. 不在之間,我們令 right = mid - 1;
時間復雜度:O(logn)选酗。

No.82.刪除排序鏈表中的重復元素Ⅱ

難度:中等
題目描述:


在這里插入圖片描述

題解代碼(Python3.8)

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if head == None or head.next == None:
            return head
        dummy = ListNode(-999)
        dummy.next = head
        slow = dummy
        fast =dummy.next
        while fast:
            while fast.next and slow.next.val == fast.next.val:
                fast = fast.next
            if slow.next == fast:
                slow = fast
            else:
                slow.next = fast.next
            fast = fast.next
        return dummy.next

或許有用的知識點:
當處理鏈表且需要考慮空鏈表時阵难,我們或許可以設置一個啞結(jié)點,即dummy=LIstNode(-999)芒填,dummy.next = head呜叫。
這道題可以用快慢指針的思想。
這道題也可以使用遞歸的思想殿衰。

解題思路:
先定義一個啞節(jié)點(注意啞節(jié)點的值不能再測試樣例中出現(xiàn))朱庆,之后運用快慢指針的思想,按照題目要求只改變指針的指向即可闷祥。

優(yōu)解代碼及分析:
優(yōu)解代碼(Python3.8)

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head:
            return head
        if head.next and (head.val == head.next.val):
            while (head.next != None) and (head.val == head.next.val):
                head = head.next
            return self.deleteDuplicates(head.next)
        else:
            head.next = self.deleteDuplicates(head.next)
        return head

分析:
這種解法使用了遞歸的思想娱颊,對鏈表層層遞歸即可。

No.83.刪除排序鏈表中的重復元素

難度:簡單
題目描述:


在這里插入圖片描述

題解代碼(Python3.8)

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        dummy = ListNode(-999)
        dummy.next = head
        slow = dummy
        fast =dummy.next
        while fast:
            if slow.val != fast.val:
                slow =slow.next
                slow.val = fast.val
            fast = fast.next
        slow.next = None
        return head

或許有用的知識點:
當處理鏈表且需要考慮空鏈表時凯砍,我們或許可以設置一個啞結(jié)點箱硕,即dummy=LIstNode(-999),dummy.next = head悟衩。
這道題可以用快慢指針的思想剧罩。
這道題也可以使用遞歸的思想。

解題思路:
這道題和上一道題‘No.82.刪除排序鏈表中的重復元素Ⅱ’思路差不多座泳,可以說是上一道題‘No.82.刪除排序鏈表中的重復元素Ⅱ’的閹割版惠昔。先定義一個啞節(jié)點(注意啞節(jié)點的值不能再測試樣例中出現(xiàn))幕与,之后運用快慢指針的思想,按照題目要求只改變指針的指向即可舰罚。

優(yōu)解代碼及分析:
優(yōu)解代碼(Python3.8)

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if not head:
            return head
        if head.next and (head.val == head.next.val):
            while head.next and (head.val == head.next.val):
                head = head.next
            return self.deleteDuplicates(head)
        else:
            head.next = self.deleteDuplicates(head.next)
        return head

分析:
這道題和上一道題‘No.82.刪除排序鏈表中的重復元素Ⅱ’思路差不多,可以說是上一道題‘No.82.刪除排序鏈表中的重復元素Ⅱ’的閹割版薛耻。這種解法使用了遞歸的思想营罢,對鏈表層層遞歸即可。

No.84.柱狀圖中最大的矩形

難度:困難
題目描述:


在這里插入圖片描述

題解代碼(Python3.8)

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        stack = []
        heights = [0] + heights + [0]
        res = 0
        for i in range(len(heights)):
            while stack and heights[stack[-1]] > heights[i]:
                #print('儲存索引的棧',stack,'其棧頂元素',heights[stack[-1]],'>當前元素',heights[i])
                tmp = stack.pop()
                #print('判斷以原棧頂元素',heights[tmp],'為左端元素向右平移得到的矩形面積',(i-stack[-1]-1)*heights[tmp],'是否比res',res,'大饼齿,更新res')
                res = max(res,(i-stack[-1]-1)*heights[tmp]) 
            stack.append(i)
            #print('將當前元素',heights[i],'入棧,此時儲存索引的棧',stack,'保證了棧仍為遞增棧')
            #print('------------- i++ ------------')
        return res

或許有用的知識點:
這道題要用到單調(diào)棧的思想饲漾。

解題思路:
這道題可以用單調(diào)遞增棧的思想,所謂用單調(diào)遞增棧解決這道題缕溉,其實可以把這個想象成鋸木板考传,如果木板都是遞增的那我很開心,如果突然遇到一塊木板i矮了一截证鸥,那我就先找之前最高的一塊(其實就是第i-1塊)僚楞,計算一下這個木板單獨的面積,然后把它鋸成次高的枉层,這是因為我之后的計算都再也用不著這塊木板本身的高度了泉褐。再然后如果發(fā)覺次高的仍然比現(xiàn)在這個i木板高,那我繼續(xù)單獨計算這個次高木板的面積(應該是第i-1和i-2塊)鸟蜡,再把它倆鋸短膜赃。直到發(fā)覺不需要鋸就比第i塊矮了,那么就再次保證了木板是遞增的揉忘,那我繼續(xù)開開心心往右找更高的跳座。當然為了避免到了最后一直都是遞增的,所以可以在最后加一塊高度為0的木板泣矛。
以heights=[2,1,5,6,2,3]為例疲眷,將代碼連帶注釋一起在IDLE運行的逐步結(jié)果如下:


在這里插入圖片描述

No.85.最大矩形

難度:困難
題目描述:


在這里插入圖片描述

題解代碼(Python3.8)

class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        if (not matrix) or (not matrix[0]):
            return 0
        l_row = len(matrix)
        l_col = len(matrix[0])
        heights = [0]*(l_col+2)
        res = 0
        for i in range(l_row):
            stack = []
            for j in range(l_col):
                if matrix[i][j] == '1':
                    heights[j+1] += 1
                else:
                    heights[j+1] =0
            #print('以第',i,'行為底,其高度數(shù)組heights為',heights)
            
            #以下同上一題‘No.84.柱狀圖中最大的矩形’
            for j in range(l_col+2):
                while stack and heights[stack[-1]] > heights[j]:
                    #print('儲存索引的棧',stack,'其棧頂元素',heights[stack[-1]],'>當前元素',heights[j])
                    tmp = stack.pop()
                    #print('判斷以原棧頂元素',heights[tmp],'為左端元素向右平移得到的矩形面積',(j-stack[-1]-1)*heights[tmp],'是否比res',res,'大您朽,更新res')
                    res = max(res,(j-stack[-1]-1)*heights[tmp]) 
                stack.append(j)
                #print('將當前元素',heights[j],'入棧,此時儲存索引的棧',stack,'保證了棧仍為遞增棧')
                #print('------------- j++ -------------')
        return res

或許有用的知識點:
這道題要用到單調(diào)棧的思想咪橙。

解題思路:
這道題其實和上一道題‘No.84.柱狀圖中最大的矩形’的解題思路很類似,在0-1二維矩陣中虚倒,逐行為底將0-1二維矩陣轉(zhuǎn)換成直方柱的形式美侦,每行解法和上一道題‘No.84.柱狀圖中最大的矩形’就一樣了,如下圖:


在這里插入圖片描述

這道題可以用單調(diào)遞增棧的思想魂奥,所謂用單調(diào)遞增棧解決這道題菠剩,其實可以把這個想象成鋸木板,如果木板都是遞增的那我很開心耻煤,如果突然遇到一塊木板i矮了一截具壮,那我就先找之前最高的一塊(其實就是第i-1塊)准颓,計算一下這個木板單獨的面積,然后把它鋸成次高的棺妓,這是因為我之后的計算都再也用不著這塊木板本身的高度了攘已。再然后如果發(fā)覺次高的仍然比現(xiàn)在這個i木板高,那我繼續(xù)單獨計算這個次高木板的面積(應該是第i-1和i-2塊)怜跑,再把它倆鋸短样勃。直到發(fā)覺不需要鋸就比第i塊矮了,那么就再次保證了木板是遞增的性芬,那我繼續(xù)開開心心往右找更高的峡眶。當然為了避免到了最后一直都是遞增的,所以可以在最后加一塊高度為0的木板植锉。
以代碼中的matrix(同題目樣例)為例辫樱,將代碼連帶注釋一起在IDLE運行,運行的代碼和代碼每一行運行的逐步結(jié)果如下:


在這里插入圖片描述

在這里插入圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俊庇,一起剝皮案震驚了整個濱河市狮暑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辉饱,老刑警劉巖心例,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鞋囊,居然都是意外死亡止后,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門溜腐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來译株,“玉大人,你說我怎么就攤上這事挺益∏该樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵望众,是天一觀的道長匪补。 經(jīng)常有香客問我,道長烂翰,這世上最難降的妖魔是什么夯缺? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮甘耿,結(jié)果婚禮上踊兜,老公的妹妹穿的比我還像新娘。我一直安慰自己佳恬,他們只是感情好捏境,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布于游。 她就那樣靜靜地躺著,像睡著了一般垫言。 火紅的嫁衣襯著肌膚如雪贰剥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天筷频,我揣著相機與錄音蚌成,去河邊找鬼。 笑死截驮,一個胖子當著我的面吹牛笑陈,可吹牛的內(nèi)容都是我干的际度。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沈堡!你這毒婦竟也來了猴蹂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤窒所,失蹤者是張志新(化名)和其女友劉穎鹉勒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吵取,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡禽额,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了皮官。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脯倒。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捺氢,靈堂內(nèi)的尸體忽然破棺而出藻丢,到底是詐尸還是另有隱情,我是刑警寧澤摄乒,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布悠反,位于F島的核電站,受9級特大地震影響馍佑,放射性物質(zhì)發(fā)生泄漏斋否。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一拭荤、第九天 我趴在偏房一處隱蔽的房頂上張望如叼。 院中可真熱鬧,春花似錦穷劈、人聲如沸笼恰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽社证。三九已至逼龟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間追葡,已是汗流浹背腺律。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宜肉,地道東北人匀钧。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像谬返,于是被迫代替她去往敵國和親之斯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容