两数之和:

 class Solution:
     def twoSum(self, nums: List[int], target: int) -> List[int]:
         count = {}
         n = len(nums)
         for i in range(n):
             if target - nums[i] not in count:
                 count[nums[i]] = i
             else:
                 return [i, count[target - nums[i]]]
         return None

go 声明 map

 // 1. make 声明
 m := make(map[int]int)
 ​
 // 2. 仅声明, 不可直接写入
 var m map[int]int

两数之和(链表):

 # 万能转换数组
 # Definition for singly-linked list.
 # class ListNode:
 #     def __init__(self, val=0, next=None):
 #         self.val = val
 #         self.next = next
 class Solution:
     def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
         if not l1:
             return l2
         if not l2:
             return l1
 ​
         num1 = ''
         num2 = ''
 ​
         while l1:
             num1 += str(l1.val)
             l1 = l1.next
 ​
         while l2:
             num2 += str(l2.val)
             l2 = l2.next
       
         # 原数字是逆序
         num1 = int(num1[::-1])
         num2 = int(num2[::-1])
         res = num1 + num2
       
         head = ListNode(res % 10)
         ans = head
         res //= 10
 ​
         while res > 0:
             node = ListNode(res % 10)
             head.next = node
             head = head.next
             res //= 10
 ​
         return ans
   
 # 模拟
 # Definition for singly-linked list.
 # class ListNode:
 #     def __init__(self, val=0, next=None):
 #         self.val = val
 #         self.next = next
 class Solution:
     def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
         head = ListNode()
         cur = head
         car = False
 ​
         while l1 or l2 or car:
             val1 = l1.val if l1 else 0
             val2 = l2.val if l2 else 0
 ​
             cnt = val1 + val2 + 1 if car else val1 + val2
             car = cnt >= 10  
           
             cur.next = ListNode(cnt % 10)
             cur = cur.next
 ​
             if l1: l1 = l1.next
             if l2: l2 = l2.next
       
         return head.next
 /**
  * Definition for singly-linked list.
  * type ListNode struct {
  *     Val int
  *     Next *ListNode
  * }
  */
 func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
     head := &ListNode{0, nil}
     cur := head
     car := false
 ​
     for l1 != nil || l2 != nil || car {
         v1, v2, sum := 0, 0, 0
         if l1 != nil {v1, l1 = l1.Val, l1.Next}
         if l2 != nil {v2, l2 = l2.Val, l2.Next}
 ​
         if car {sum = v1 + v2 + 1}else{sum = v1 + v2}
       
         car = sum >= 10
 ​
         cur.Next = &ListNode{sum % 10, nil}
         cur = cur.Next
     }
     return head.Next
 }

在go里面, 声明一个结构体字面量有一个语法糖, 可以快速得到一个结构体的指针

p := &ListNode{Val: 3}

Q: 如果没有 &, 直接得到值不行吗?

A:不行, 结构体里面明确了 Next字段是一个指针, 所以必须使用指针才能连起来一个链表

无重复字符的最长子串

 class Solution:
     def lengthOfLongestSubstring(self, s: str) -> int:
         l, r, n = 0, 1, len(s)
         res = 1
         max_res = 1
 ​
         if n <= 1:
             return n
 ​
         count = set(s[l])
 ​
         while r < n:
             while s[r] in count:
                 count.remove(s[l])
                 l += 1
                 res -= 1
             else:  
                 count.add(s[r])
                 res += 1
           
             max_res = max(max_res, res)
             r += 1
 ​
         return max_res
   
 # 优化版
 class Solution:
     def lengthOfLongestSubstring(self, s: str) -> int:
         l, n, res = 0, len(s), 1
 ​
         if n <= 1:
             return n
 ​
         count = set()
 ​
         for r, val in enumerate(s):
             while val in count:
                 count.remove(s[l])
                 l += 1
 ​
             count.add(val)          
             res = max(res, r - l + 1)
 ​
         return res
 ​
 # 跳左指针, 记录字符的最后一个出现位置
 def lengthOfLongestSubstring(s: str) -> int:
     last = {}
     l = 0
     best = 0
     for r, ch in enumerate(s):
         if ch in last and last[ch] >= l:
             l = last[ch] + 1
         last[ch] = r
         best = max(best, r - l + 1)
     return best
 // 定位跳指针法
 func lengthOfLongestSubstring(s string) int {
     l, res := 0, 0
 ​
     count := make(map[rune]int)
 ​
     for r, val := range s {
         index, ok := count[val]
         if ok && index >= l{
             l = index + 1
         }
         count[val] = r
         res = max(res, r - l + 1)
     }
     return res
 }

乘最多水的容器

 class Solution(object):
     def maxArea(self, height):
         """
         :type height: List[int]
         :rtype: int
         """
         l, r = 0, len(height) - 1
         res = 0
 ​
         while l < r:
             cur = (r - l) * min(height[l], height[r])
             res = max(res, cur)
             if height[l] > height[r]:
                 r -= 1
             else:
                 l += 1
               
         return res
 func maxArea(height []int) int {
     n := len(height)
     l, r := 0, n - 1
     res := 0
 ​
     for l < r{
         cur := min(height[l], height[r]) * (r - l)
         res = max(res, cur)
         if height[l] < height[r]{
             l ++
         }else{
             r --
         }
     } 
     return res
 }

罗马数字转整数

class Solution:
    def romanToInt(self, s: str) -> int:
        dic = {
            'I': 1,
            'V': 5,
            'X': 10,
            'L': 50,
            'C': 100,
            'D': 500,
            'M': 1000
        }
        s = s[::-1]
        ans = dic[s[0]]
        for i in range(1, len(s)):
            if dic[s[i]] < dic[s[i - 1]]:
                ans -= dic[s[i]]
            else:
                ans += dic[s[i]]

        return ans
func romanToInt(s string) int {
    dic := map[byte]int{
        'I': 1,
        'V': 5,
        'X': 10,
        'L': 50,
        'C': 100,
        'D': 500,
        'M': 1000,
    }
    n := len(s)
    ans := dic[s[n - 1]]
    for i := n - 2; i >= 0; i--{
        if dic[s[i]] < dic[s[i + 1]] {
            ans -= dic[s[i]] 
        }else {
            ans += dic[s[i]]
        }
    }
    return ans
}

最长公共前缀

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        min_len = len(strs[0])
        min_ans = strs[0]

        for i in strs:
            if len(i) < min_len:
                min_len = len(i)
                min_ans = i

        for i in range(min_len):
            for j in range(len(strs)):
                cur = strs[0][i]
                if strs[j][i] != cur:
                    return strs[j][:i]

        return min_ans
func longestCommonPrefix(strs []string) string {
    minLen := len(strs[0])
    minAns := strs[0]

    for _, v := range strs{
        if len(v) < minLen{
            minLen = len(v)
            minAns = v
        }
    }

    for i := 0; i < minLen; i++{
        for j := 0; j < len(strs); j++{
            cur := strs[0][i]
            if strs[j][i] != cur{
                return strs[j][:i]
            }
        }
    }

    return minAns
}

大小为 k 且平均值大于分股阈值的子数组数目

class Solution:
    def numOfSubarrays(self, arr: List[int], k: int, threshold: int) -> int:
        n, tar = len(arr), k * threshold

        if k > n:
            return 0

        cur = sum(arr[:k])
        ans = 1 if cur >= tar else 0

        for r in range(k, len(arr)):
            l = r - k
            cur -= arr[l]
            cur += arr[r]
            if cur >= tar:
                ans += 1

        return ans
# 优化版
class Solution:
    def numOfSubarrays(self, arr: List[int], k: int, threshold: int) -> int:
        n, tar = len(arr), k * threshold

        cur = sum(arr[:k])
        ans = int(cur >= tar)

        for r in range(k, n):
            l = r - k
            cur += arr[r] - arr[l]
            ans += int(cur >= tar)

        return ans

字母异位词分组

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        ans = {}

        for i in strs:
            list_i = list(i)
            list_i.sort()
            cur = "".join(list_i)
            if cur not in ans:
                ans[cur] = [i]
            else:
                ans[cur].append(i)

        return list(ans.values())
# 优化版, defaultdict 在访问一个不存在的 key 时,会自动创建一个默认值,而不会报错。
from collections import defaultdict
class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        ans = defaultdict(list) # 入参为键不存在的时候的默认值

        for i in strs:
            cur = "".join(sorted(i))
            ans[cur].append(i)

        return list(ans.values())

经验

  1. 快读代替scan

    reader := bufio.NewReader(os.Stdin)

    line, err := reader.Readstrings(‘\n’)

    // 注意go不能像py一样动态改变变量类型

    fields := strings.Fields(line)

一天是牛马, 一辈子是牛马