📜  面试问题中排名前 10 的算法(1)

📅  最后修改于: 2023-12-03 15:12:51.696000             🧑  作者: Mango

面试问题中排名前 10 的算法

在程序员面试中,常常会被问到一些常见的算法问题。下面是排名前 10 的常见算法问题及其解答。

1. 两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。可以假设每个输入只对应一种答案,且数组中同样的元素不能使用两遍。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashmap = {}
        for i, num in enumerate(nums):
            if target - num in hashmap:
                return [hashmap[target - num], i]
            hashmap[num] = i
2. 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 。找出所有满足条件且不重复的三元组。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        nums.sort()
        for i in range(len(nums)-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l, r = i+1, len(nums)-1
            while l < r:
                s = nums[i] + nums[l] + nums[r]
                if s < 0:
                    l += 1
                elif s > 0:
                    r -= 1
                else:
                    res.append([nums[i], nums[l], nums[r]])
                    while l < r and nums[l] == nums[l+1]:
                        l += 1
                    while l < r and nums[r] == nums[r-1]:
                        r -= 1
                    l += 1; r -= 1
        return res
3. 四数之和

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d = target ?找出所有满足条件且不重复的四元组。

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        def nSum(nums, n, target):
            res = []
            if len(nums) < n or n < 2 or target < n * nums[0] or target > n * nums[-1]:
                return res
            if n == 2:
                l, r = 0, len(nums) - 1
                while l < r:
                    s = nums[l] + nums[r]
                    if s == target:
                        res.append([nums[l], nums[r]])
                        l += 1
                        r -= 1
                        while l < r and nums[l] == nums[l - 1]:
                            l += 1
                        while l < r and nums[r] == nums[r + 1]:
                            r -= 1
                    elif s > target:
                        r -= 1
                    else:
                        l += 1
                return res
            else:
                for i in range(len(nums)):
                    if i > 0 and nums[i] == nums[i - 1]:
                        continue
                    for item in nSum(nums[i + 1:], n - 1, target - nums[i]):
                        res.append([nums[i]] + item)
                return res
        return nSum(sorted(nums), 4, target)
4. 最长子序列和

给定一个整数数组,找到一个具有最大和的连续子数组,返回其最大和。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        max_sum = nums[0]
        cur_sum = 0
        for num in nums:
            cur_sum += num
            max_sum = max(max_sum, cur_sum)
            cur_sum = max(cur_sum, 0)
        return max_sum
5. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if not s:
            return ""
        n = len(s)
        result = ""
        for i in range(n):
            cur = self.helper(s, i, i)
            if len(cur) > len(result):
                result = cur
            cur = self.helper(s, i, i + 1)
            if len(cur) > len(result):
                result = cur
        return result

    def helper(self, s, l, r):
        n = len(s)
        while l >= 0 and r < n and s[l] == s[r]:
            l -= 1
            r += 1
        return s[l + 1:r]
6. 正则表达式匹配

给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        m, n = len(s), len(p)
        dp = [[False] * (n + 1) for _ in range(m + 1)]
        dp[0][0] = True
        for i in range(n):
            if p[i] == '*' and dp[0][i - 1]:
                dp[0][i + 1] = True
        for i in range(m):
            for j in range(n):
                if p[j] == '.' or p[j] == s[i]:
                    dp[i + 1][j + 1] = dp[i][j]
                elif p[j] == '*':
                    if p[j - 1] != s[i] and p[j - 1] != '.':
                        dp[i + 1][j + 1] = dp[i + 1][j - 1]
                    else:
                        dp[i + 1][j + 1] = (dp[i + 1][j] or dp[i][j + 1] or dp[i + 1][j - 1])
        return dp[-1][-1]
7. 合并区间

给出一个区间的集合,请合并所有重叠的区间。

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        if not intervals:
            return []
        intervals.sort()
        merged = []
        for interval in intervals:
            if not merged or merged[-1][1] < interval[0]:
                merged.append(interval)
            else:
                merged[-1][1] = max(merged[-1][1], interval[1])
        return merged
8. 单词搜索

给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平或垂直相邻的单元格,同一个单元格内的字母不允许被重复使用。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        if not board:
            return False
        if not word:
            return True
        for i in range(len(board)):
            for j in range(len(board[0])):
                if self.dfs(board, i, j, word):
                    return True
        return False

    def dfs(self, board, i, j, word):
        if len(word) == 0:
            return True
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]) or board[i][j] != word[0]:
            return False
        tmp = board[i][j]
        board[i][j] = "#"
        res = self.dfs(board, i + 1, j, word[1:]) or self.dfs(board, i - 1, j, word[1:]) \
              or self.dfs(board, i, j + 1, word[1:]) or self.dfs(board, i, j - 1, word[1:])
        board[i][j] = tmp  # 恢复原状
        return res
9. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []
        hash_map = {"2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"}
        res = []
        self.dfs(digits, hash_map, "", res)
        return res

    def dfs(self, digits, hash_map, cur, res):
        if not digits:
            res.append(cur)
            return
        for c in hash_map[digits[0]]:
            self.dfs(digits[1:], hash_map, cur + c, res)
10. 全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        if not nums:
            return []
        res = []
        visited = set()
        self.dfs(nums, [], visited, res)
        return res

    def dfs(self, nums, cur, visited, res):
        if len(cur) == len(nums):
            res.append(cur[:])
            return
        for num in nums:
            if num not in visited:
                cur.append(num)
                visited.add(num)
                self.dfs(nums, cur, visited, res)
                visited.remove(num)
                cur.pop()