面试金典06(Python)—— 字符串压缩(简单)

字符串压缩

概述:字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串 aabcccccaaa 会变为 a2b1c5a3 。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

输入:"aabcccccaaa"
输出:"a2b1c5a3"

输入:"abbccd"
输出:"abbccd"

方法一:暴力循环

思路:依旧第一反应是双重循环,定义个 num 作为标记,如果字符串相等,则 num +1 。但是发现第一次循环中会重新出现,所以加上前后字符串判决即可。因为从 0 开始,最后再对首字符串单独判断即可。

# 暴力循环
class Solution:
    def compressString(self, S: str) -> str:
        ans = ''
        n = len(S)
        for i in range(n):
            if i != 0 and S[i] != S[i - 1]:
                num = 1
                for j in range(i + 1, n):
                    if S[i] == S[j]:
                        num += 1
                    else:
                        break
                ans += S[i]
                ans += str(num)
            if i == 0:
                num = 1
                for j in range(i + 1, n):
                    if S[i] == S[j]:
                        num += 1
                    else:
                        break
                ans += S[i]
                ans += str(num)
        return ans if len(ans) < len(S) else S

方法二:逆序弹栈

思路:该算法利用弹栈的思路,逆向进行循环。若列表中最后一个值与前一个值相等,弹栈。一直到不相等时输出。但是对于第一个值需要单独处理。

# 逆序弹栈
class Solution:
    def compressString(self, S: str) -> str:
        S_list = list(S)
        ans = []
        n = len(S_list)
        num = 1
        if n == 1 or n == 2:
            return S
        for i in range(n - 1, -1, -1):
            if i != 0 and S_list[i] == S_list[i - 1]:
                S_list.pop()
                num += 1
            else:
                ans.append(S_list[i] + str(num))
                num = 1
        ans_s = ''.join(ans[::-1])
        return ans_s if len(ans_s) < len(S) else S

方法三:

思路:定义一个哨点指针 target ,依次对 S 进行循环。若相等,次数 num += 1 ,若不相等,更新 target num

# 哨点指针
class Solution:
    def compressString(self, S: str) -> str:
        if not S:
            return ''
        target = S[0]
        num = 0
        ans = ''
        for i in S:
            if i == target:
                num += 1
            else:
                ans += target + str(num)
                target = i
                num = 1
        ans += target + str(num)
        return ans if len(ans) < len(S) else S

方法四:快慢指针

思路:该算法是对暴力循环的一种改进。优势在于快慢指针能够有效地减少循环范围。即快慢指针相等时,再对快指针 fast += 1进行判断。

# 快慢指针
class Solution:
    def compressString(self, S: str) -> str:
        fast, slow = 0, 0
        n = len(S)
        ans = ''
        while slow < n:
            while fast < n and S[fast] == S[slow]:
                fast += 1
            ans += S[slow] + str((fast - slow))
            slow = fast
        return ans if len(ans) < len(S) else S

总结

这题能睡个好觉:)

你可能感兴趣的:(数据结构,python,算法,面试,职场和发展)