Python —— 简单练手算法

1. 交替合并字符串(mergeAlternately)

这个算法的需求是,给你两个字符串 word1word2,要从 word1 开始,交替添加字母来合并字符串。要是一个字符串比另一个长,就把多出来的字母追加到合并后字符串的末尾。

class Solution(object):
    def mergeAlternately(self, word1, word2):
        result = []
        min_len = min(len(word1), len(word2))
        for i in range(min_len):
            result.append(word1[i])
            result.append(word2[i])
        result.append(word1[min_len:])
        result.append(word2[min_len:])

        return ''.join(result)

我觉得这个算法的关键在于先找出两个字符串的最短长度,然后交替添加字符,最后再把剩下的部分加上去。

2. 判断数组元素乘积的符号(arraySign)

这个算法是已知一个函数 signFunc(x),它会根据 x 的正负返回特定值:正数返回 1,负数返回 -1,0 返回 0。现在给你一个整数数组 nums,要返回 signFunc(product),这里的 product 是数组 nums 中所有元素值的乘积。

class Solution(object):
    def arraySign(self, nums):
        result = 1
        for n in nums:
            result *= n
        if result > 0:
            return 1
        elif result < 0:
            return -1
        else:
            return 0

    def arraySign2(self, nums):
        count = 0
        for num in nums:
            if num == 0:
                return 0
            if num < 0:
                count += 1

        return 1 if count % 2 == 0 else -1

这里有两种方法,第一种是直接算出乘积再判断符号,但如果数组很长,乘积可能会超出限制。第二种方法就很巧妙,只统计负数的个数,通过判断负数个数的奇偶性来确定最终结果。

3. 移动零到数组末尾(moveZeroes)

需求是给定一个数组 nums,要把所有的 0 移动到数组的末尾,同时保持非零元素的相对顺序,而且必须在不复制数组的情况下原地操作。

class Solution(object):
    def moveZeroes(self, nums):
        i = 0
        for j in range(len(nums)):
            if nums[j] != 0:
                nums[i], nums[j] = nums[j], nums[i]
                i += 1

这个算法用了双指针的思想,一个指针 i 用来记录非零元素的位置,另一个指针 j 遍历数组,遇到非零元素就交换位置。

4. 判断数组是否单调(isMonotonic)

如果数组是单调递增或单调递减的,那它就是单调的。要判断给定的数组 nums 是否单调。

class Solution(object):
    def isMonotonic(self, nums):
        if len(nums) < 2:
            return True
        increasing = decreasing = True
        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                decreasing = False
            if nums[i] < nums[i - 1]:
                increasing = False
        return increasing or decreasing

这里通过同时判断数组是否递增和递减来确定最终结果,思路很清晰。

5. 判断是否为字母异位词(isAnagram)

给定两个字符串 st,要判断 t 是否是 s 的字母异位词。

class Solution(object):
    def isAnagram(self, s, t):
        return sorted(s) == sorted(t)

这个算法就很简单啦,直接对两个字符串排序,然后比较是否相等就行。

6. 找出字符串中添加的字母(findTheDifference)

给定两个只包含小写字母的字符串 stt 是由 s 随机重排,然后在随机位置添加一个字母得到的,要找出这个添加的字母。

class Solution(object):
    def findTheDifference(self, s, t):
        result = 0
        for char in s + t:
            result ^= ord(char)
        return chr(result)

这里用到了异或运算的特性,相同字符异或结果为 0,最后剩下的就是添加的字母。

7. 罗马数字转整数(romanToInt)

罗马数字有特定的字符和数值对应关系,要把给定的罗马数字转换成整数。

class Solution(object):
    def romanToInt(self, s):
        n = len(s)
        result = 0
        arr = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
        for i in range(n):
            value = arr[s[i]]
            if i < n - 1 and value < arr[s[i + 1]]:
                result -= value
            else:
                result += value

        return result

这个算法的关键在于处理罗马数字的特殊规则,比如 IV 表示 4 这种情况。

8. 检查字符串是否由子串重复构成(repeatedSubstringPattern)

给定一个非空的字符串 s,要检查是否可以通过它的一个子串重复多次构成。

class Solution(object):
    def repeatedSubstringPattern(self, s):
        return s in (s + s)[1:-1]

这个算法的思路很巧妙,把字符串 s 拼接成 s + s,然后去掉首尾字符,看 s 是否在其中。

9. 判断数组能否构成等差数列(canMakeArithmeticProgression)

给你一个数字数组 arr,判断是否可以重新排列数组形成等差数列。

class Solution(object):
    def canMakeArithmeticProgression(self, arr):
        arrSorted = sorted(arr)
        num = 0
        l = len(arrSorted)
        if l > 1:
            num = arrSorted[0] - arrSorted[1]
        for i in range(0, len(arrSorted) - 1, 1):
            if (arrSorted[i] - arrSorted[i + 1]) != num:
                return False

        return True

    def canMakeArithmeticProgression2(self, arr):
        if len(arr) < 2:
            return True
        arr_sorted = sorted(arr)
        common_difference = arr_sorted[1] - arr_sorted[0]
        for i in range(2, len(arr_sorted)):
            if arr_sorted[i] - arr_sorted[i - 1] != common_difference:
                return False
        return True

这里有两种方法,核心思想都是先排序,然后检查相邻元素的差值是否相等。

10. 字符串匹配(strStr)

给你两个字符串 haystackneedle,要在 haystack 中找出 needle 的第一个匹配项的下标,如果 needle 不是 haystack 的一部分,则返回 -1。

class Solution(object):
    def strStr(self, haystack, needle):
        def get_lps(pattern):
            m = len(pattern)
            lps = [0] * m
            length = 0
            i = 1
            while i < m:
                if pattern[i] == pattern[length]:
                    length += 1
                    lps[i] = length
                    i += 1
                else:
                    if length != 0:
                        length = lps[length - 1]
                    else:
                        lps[i] = 0
                        i += 1
            return lps

        n = len(haystack)
        m = len(needle)
        if m == 0:
            return 0
        lps = get_lps(needle)
        i = 0
        j = 0
        while i < n:
            if needle[j] == haystack[i]:
                i += 1
                j += 1
            if j == m:
                return i - j
            elif i < n and needle[j] != haystack[i]:
                if j != 0:
                    j = lps[j - 1]
                else:
                    i += 1
        return -1

这个算法用了 KMP 算法,通过预处理 needle 字符串得到 lps 数组,来避免不必要的回溯。(这个有一点难度,简单一点的就是直接暴力区配)

11. 数组表示的整数加一(plusOne)

给定一个由整数组成的非空数组表示的非负整数,要在这个数的基础上加一。

class Solution(object):
    def plusOne(self, digits):
        n = len(digits)
        for i in range(n - 1, -1, -1):
            if digits[i] < 9:
                digits[i] += 1
                return digits
            digits[i] = 0

        return [1] + digits

这个算法从数组的最后一位开始遍历,如果小于 9 就加一返回,如果是 9 就置为 0,最后如果所有位都是 9,就在数组前面加一个 1。

大家有什么问题或者想法,欢迎在评论区留言交流



细节决定成败!
个人愚见,如有不对,恳请斧正!

posted @ 2025-04-12 13:03  一点浩然气~  阅读(59)  评论(0)    收藏  举报