首先是 557. Reverse Words in a String III (easy)
https://leetcode.com/problems/reverse-words-in-a-string-iii/
題目要求很簡單,會給一個串列s,裡面有很多單字,字與字之間有一格空格。要把每個單字都進行翻轉。
雖然標籤有two pointer,但python做這題用pointer反而覺得有點矯情。
就簡單用個split() + [::-1]就解決了
class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.split(" ")
        for i in range(len(s)):
            s[i] = s[i][::-1]
        return " ".join(s)
再來是 121. Best Time to Buy and Sell Stock (easy)
https://leetcode.com/problems/best-time-to-buy-and-sell-stock
這題題目會給一個叫做price的list,裡面所存的數字可以當作是某項物品的價位。
當只能買賣一次時,能夠賺取的最大金額為多少(買的日期一定要比賣的日期早)
像這種題目首先要試的方法當然就是暴力法:
兩層for迴圈,把後面所有的數字都減過一遍,找最小值直接取絕對值就結束了。
class Solution:
    def maxProfit(self, price: List[int]) -> int:
        #這樣寫果然會TLE
        ansList = [0]
        for i in range(len(prices)):
            for j in range(i+1,len(prices)):
                temp = prices[i] - prices[j]
                if temp < 0:
                    ansList.append(temp)
        ans = min(ansList)
        return abs(ans)
那像這種毫無效率的方法會TLE就不意外。
因此接下來改成以下的作法
class Solution:
        #這題是用兩個pointer沒有錯,從前往後
        ansList = [0]
        front ,back = 0, 1
        while back<len(price):
            if price[front] >= price[back]:
                front = back
                back +=1
                
            else:
                ansList.append(price[back] - price[front])
                back +=1
        ans = max(ansList)
        return ans
接下來是 409. Longest Palindrome (easy)
https://leetcode.com/problems/longest-palindrome
這題會給一個字串s,要從這s裡面拼湊出回文字串,並且找出最長的長度。
想法:
class Solution:
    #別忽略了可以是多個奇數的狀況ex:3個a、5個b
    #別忘記一件事情奇數個東西也可以變成偶數阿-1就好
    #簡單來說我只要計算有多少個奇數就好假設有3個奇數就總字數-2,n個奇數就總字數-(n-1)
    def longestPalindrome(self, s: str) -> int:
        sDict = Counter(s)
        # print(sDict)
        count = 0
        flag = 0 
        for i in sDict.values():
            if i % 2:
                flag = 1
                count += i-1
            else:
                count += i
        if flag:
            return count+1
        return count
這是一開始的想法,但這樣寫其實有幾個問題
class Solution:
    #別忽略了可以是多個奇數的狀況ex:3個a、5個b
    #別忘記一件事情奇數個東西也可以變成偶數阿-1就好
    #簡單來說我只要計算有多少個奇數就好假設有3個奇數就總字數-2,n個奇數就總字數-(n-1)
    def longestPalindrome(self, s: str) -> int:
        sDict = Counter(s)
        flag = 0
        for i in sDict.values():
            if i % 2:
                flag += 1
        if flag:
            return len(s) - flag + 1
        else:
            return len(s)
相對而言簡單很多,指需要統計奇數有多少個,超過一個的話扣掉他即可。
下一題 142. Linked List Cycle II (medium)
https://leetcode.com/problems/linked-list-cycle-ii/
需要思考一下的題目
要求找出這個linked list是否cycle,以及從哪個node開始cycle

由圖可知,從back走了A+B到撞擊點,也就是說front要走2A+2B-1若中間跑loop跑了n圈,距離為nL,則可以這樣說 A+B+nL = 2A+2B-1 -> A+B-1 = nL 我們要找的A就是nL-B+1,那因為跟跑操場一樣,每圈長度固定,所以可以簡寫為L-B+1。
所以首先第一步,使用Floyd確定是否為cycle後
第二步就是back跟head一起往前L-B步即可,由於front有偷走一步,所以back也要先走一步把那個+1去掉。
所以會變成以下的程式碼
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        #龜兔賽跑檢查是否為cycle
        if head is None or head.next is None:
            return None
        back = head
        front = head.next
        flag = 0
        while front:
            if flag:
                back = back.next
                flag = 0
                front = front.next
                if front == back:
                    break
            else:
                front = front.next
                flag = 1
        else:
            return None
        #尋找重複開始的地方
        back = back.next
        while head != back:
            head = head.next
            back = back.next
        return head
    
稍微參考一下別人的想法以及簡化,程式碼又可以變成如下:
class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        back,front = head,head
        while front and front.next:
            front = front.next.next
            back = back.next
            if back == front:
                while head != back:
                    head = head.next
                    back = back.next
                return head
        return None