zoukankan      html  css  js  c++  java
  • 【面试题4】替换空格

    【题目描述】

    请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.”,则输出“We%20are%20happy.”。

    【解决方案】

    1. 时间复杂度为O(n^2)

    因为空格替换成“%20”之后,增加了两个字符,可能会造成原来的字符串放不下修改之后的字符串,需要遍历原来的字符串,根据空格的数量来新建一个容量足够的新数组。

    最容易想到的办法,从前往后依次遍历,遇到空格则把其后所有字符往后移动两位。

    假设字符串的长度是n,对每个空格字符,需要移动后面的0(n)个字符,因此对含有0(n)个空格字符的字符串而言总的时间效率是0(n^2)。

    我们可以尝试从后往前遍历。

    2. 时间复杂度为O(n)

    设置两个指针为p1,p2,分别放到原始字符串的末尾和新字符串的末尾,从后往前,直到p1==p2,则证明替换已经完成。如图,

    我的代码实现,仅供参考:

     1         public string ReplaceBlank(string str)
     2         {
     3             if (str == null)
     4                 return null;
     5 
     6             int length = str.Length, spaceNum = 0;
     7 
     8             foreach (char c in str)
     9             {
    10                 if (c == ' ')
    11                     spaceNum++;
    12             }
    13 
    14             char[] newStr = new char[length + spaceNum * 2];
    15 
    16             int pOld = length - 1, pNew = newStr.Length - 1;
    17 
    18             while (pOld >= 0)
    19             {
    20                 if (str[pOld] != ' ')
    21                 {
    22                     newStr[pNew] = str[pOld];
    23                 }
    24                 else
    25                 {
    26                     newStr[pNew - 2] = '%';
    27                     newStr[pNew - 1] = '2';
    28                     newStr[pNew] = '0';
    29                     pNew -= 2;
    30                 }
    31                 pOld--;
    32                 pNew--;
    33             }
    34 
    35             return new string(newStr);
    36         }

    【本题扩展】

    有两个排序数组A1和A2,内存是A1的末尾有足够多的空余空间能够容纳A2。请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字是排序的。

    和前面的例题一样,很多人首先想到的办法是在A1中从头到尾复制数字,但是这样就会出现多次复制一个数字的情况。更好的办法是从尾到头比较A1和A2中的数字,并把比较大的数字复制到A1中的合适位置。

    我的代码实现,仅供参考:

     1         public void MergeSortedArray(int?[] arrA, int?[] arrB)
     2         {
     3             //lenA表示arrA不为null部分的长度
     4             int lenA = 0, lenB = arrB.Length;
     5 
     6             foreach (int? num in arrA)
     7             {
     8                 if (num != null)
     9                     lenA++;
    10                 else
    11                     break;
    12             }
    13 
    14             int pA = lenA - 1, pB = lenB - 1;
    15 
    16             while (pB >= 0)
    17             {
    18                 if (arrA[pA] > arrB[pB])
    19                 {
    20                     arrA[pA + pB + 1] = arrA[pA];
    21                     pA--;
    22                 }
    23                 else
    24                 {
    25                     arrA[pA + pB + 1] = arrB[pB];
    26                     pB--;
    27                 }
    28             }
    29         }

    【举一反三】

    合并两个数组(包括字符串)时,如果从前往后复制每个数字(或字符)需要重复移动数字(或字符)多次,那么我们可以考虑从后往前复制,这样就减少了移动的次数,从而提高效率。

  • 相关阅读:
    Java8_Stream_了解
    Java8_方法引用和构造器引用
    Java8_函数式接口
    Java8_表达式语法
    Spring注解
    Spring_IOC笔记
    一台电脑访问另一台电脑上的VMware
    Vmware 新装centos7 ping 百度 出现 unknow host
    Windows下的免安装版MySQL配置
    Springboot2 注解@Import的使用
  • 原文地址:https://www.cnblogs.com/HuoAA/p/4797060.html
Copyright © 2011-2022 走看看