字符串-剑指offer5替换空格(合并两个已排序数组)-简单-20210808python

字符串-剑指offer5替换空格-简单-20210808

1. 题目描述

请实现一个函数,把字符串 s 中的每个空格替换成"%20"

示例

输入:s = "We are happy."
输出:"We%20are%20happy."

2. 题目解答

2.1 常规解法

  • 在 Python 和 Java 等语言中,字符串都被设计成**「不可变」的类型**,即无法直接修改字符串的某一位字符,需要新建一个字符串实现。

  • C++可以修改字符串,可以用双指针的方法

  • 需要注意不用列表直接用新字符串导致空间复杂度加大,因为每次字符串相加新建了一个新字符串(python字符串是不可变的,每次修改都会开辟一个新字符串,所以直接修改字符串空间复杂度是 O ( n 2 ) O(n^{2}) O(n2))

时间复杂度:O(n)

空间复杂度:O(n)

思路:

  • ① 不初始化一个 list (Python) / StringBuilder (Java) ,记为 res ;
  • ② 遍历列表 s 中的每个字符 s :
    • 当 s为空格时:向 res 后添加字符串 “%20” ;
    • 当 s 不为空格时:向 res 后添加字符 s ;
  • ③ 将列表 res 转化为字符串并返回。
class Solution(object):
    def replace_space(self, str):
        if not str or len(str) == 0 : return False
        res = []
        for s in str:
            if s == ' ': res.append('%20')
            else: res.append(s)
        return ''.join(res)



if __name__ == '__main__':
    # Test case
    str1 = 'We are happy'
    str2 = 'HelloWorld'
    str3 = ''
    str4 = '   '

    Solution = Solution()
    print(Solution.replace_space(str1))
    print(Solution.replace_space(str2))
    print(Solution.replace_space(str3))
    print(Solution.replace_space(str4))

2.2 运用python内置函数

时间复杂度:O(n)

空间复杂度:O(n)

  • ① 直接使用replace,原理如上面解法

  • ② 使用split+join

class Solution(object):
    def replace_space2(self, str):
        if not str or len(str) == 0 : return False
        str = str.replace(' ', '%20')
        return str

    def replace_space3(self, str):
        if not str or len(str) == 0 : return False
        return '%20'.join(str.split(' '))

2.3 C++双指针

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0, len = s.size();
        // 统计空格数量
        for (char c : s) {
            if (c == ' ') count++;
        }
        // 修改 s 长度
        s.resize(len + 2 * count);
        // 倒序遍历修改
        for(int i = len - 1, j = s.size() - 1; i < j; i--, j--) {
            if (s[i] != ' ')
                s[j] = s[i];
            else {
                s[j - 2] = '%';
                s[j - 1] = '2';
                s[j] = '0';
                j -= 2;
            }
        }
        return s;
    }
};

3. 测试用例

1. 空字符串;只有一个空格字符;连续多个空格
2. 输入的字符串中包含空格(位置:最前面/最后面/中间;连续多个空格)
3. 输入的字符串中不包含空格

4. 相关题目-合并两个已排序数组

有两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2。

请实现一个函数,把A2中的所有数字插入A1中,并且所有的数字是排序的

思路:

  • 若将A1从头到尾复制数字,会出现多次复制一个数字的情况,时间复杂度O(n*n) n2
  • 从尾到头比较A1和A2中的数字,并把较大的数字复制到A1中的合适位置
class Solution(object):
    def sort_array(self, arr1, arr2):
        if not arr1 and not arr2: return False
        if not arr1 or not arr2: return arr1+arr2

        arr1_index, arr2_index = len(arr1)-1, len(arr2)-1
        merged_index = len(arr1) + len(arr2) -1
        arr1 = arr1 + arr2 #  给数组1 扩展好空间,不让直接赋值超过原数组1的长度,会溢出
        while merged_index >= 0 and arr1_index >= 0 and arr2_index >= 0:  # 一定要加上三个条件,否则会索引到负数
            if arr1[arr1_index] >= arr2[arr2_index]:
                arr1[merged_index] = arr1[arr1_index]
                arr1_index -= 1
                merged_index -= 1
            if arr1[arr1_index] < arr2[arr2_index]:
                arr1[merged_index] = arr2[arr2_index]
                arr2_index -= 1
                merged_index -= 1

        while arr1_index >= 0:  #  带等于号,否则一个数组索引-1,另一个到索引=0的就不判断了
            arr1[merged_index] = arr1[arr1_index]
            arr1_index -= 1
            merged_index -= 1
        while arr2_index >= 0:
            arr1[merged_index] = arr2[arr2_index]
            arr2_index -= 1
            merged_index -= 1

        return arr1

if __name__ == '__main__':
    # Test case
    a0 = []
    a1 = []
    a2 = [1, 2, 2, 3]
    a3 = [2, 4, 5]
    a4 = [4, 9, 11]
    a5 = [0]
    a6 = [1, 2, 3]

    #print(a2+a5)
    Solution = Solution()
    print(Solution.sort_array(a0, a1))
    print(Solution.sort_array(a0, a2))
    print(Solution.sort_array(a2, a3))
    print(Solution.sort_array(a2, a4))
    print(Solution.sort_array(a2, a5))
    print(Solution.sort_array(a4, a6))


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值