您的位置:首页 > 职场人生

面试题(五)替换空格

2018-02-01 20:00 309 查看
题目:实现一个函数,把字符串中的每个空格替换成“%20”。如输入“We are happy”,输出“We%20are%20happy”。

思路:

1. 可以从前到后扫描字符串,每遇到空格便将其后的元素往后移动两位,然后写入“%20”。这样会有元素被移动多次。算法的时间复杂度为O(n^2)。

2. 先扫描字符串得到字符串中空格的数量,再从后往前扫描字符串:设置两个指针,一个指针newEnd指向替换后字符串的尾部,一个指针originalEnd指向原字符串尾部(此处用字符数组表示字符串,并且字符数组的空间足够大)。若originalEnd指向的元素非空格,则进行元素移动,否则进行替换。当两个指针重合时,替换结束。

代码(含单元测试):

public class Q5{

public static void main(String[] args){
Q5 q5 = new Q5();

q5.test1();
q5.test2();
q5.test3();
q5.test4();
q5.test5();
q5.test6();
}

// length is the number of characters in the string
public void replaceBlank(char[] string, int length){

if(string == null || length <= 0)
return;

int blankNum = 0;

for(int i = 0; i < length; i++)
if(string[i] == ' ')
blankNum++;

int originalEnd = length - 1;
int newEnd = originalEnd + blankNum * 2;

while(originalEnd >= 0 && originalEnd < newEnd){
if(string[originalEnd] == ' ')
{
string[newEnd--] = '0';
string[newEnd--] = '2';
string[newEnd--] = '%';
}
else
string[newEnd--] = string[originalEnd];

originalEnd--;
}

}

// mutilple blank
public void test1(){

char[] string = new char[50];
string[0] = 'A';
string[1] = ' ';
string[2] = 'o';
string[3] = 'h';
string[4] = 'j';
string[5] = ' ';
string[6] = 'k';
replaceBlank(string, 7);

for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();
}

// consecutive blank in the head
public void test2(){

char[] string = new char[50];
string[0] = ' ';
string[1] = ' ';
string[2] = 'o';
string[3] = 'e';
string[4] = 'r';
string[5] = ' ';
string[6] = 'r';
string[7] = 'w';
string[8] = 'j';
string[9] = 'q';
string[10] = 'e';
replaceBlank(string, 11);

for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();
}

// consecutive blank in the tail
public void test3(){

char[] string = new char[50];
string[0] = 'y';
string[1] = ' ';
string[2] = 's';
string[3] = 'e';
string[4] = 'i';
string[5] = ' ';
string[6] = ' ';
replaceBlank(string, 7);

for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();
}

//no blank
public void test4(){

char[] string = new char[50];
string[0] = 'y';
string[1] = 'd';
string[2] = 'd';
string[3] = 'e';
string[4] = 's';
string[5] = 'j';
string[6] = 'r';
replaceBlank(string, 7);

for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();
}

// null
public void test5(){

replaceBlank(null, 0);

/*for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();*/
}

// just one blank
public void test6(){

char[] string = new char[50];
string[0] = ' ';

replaceBlank(string, 1);

for(int i = 0; i < string.length; i++)
System.out.printf("%c ", string[i]);
System.out.println();

}

}


性能:

由于字符串中所有字符(或许没有所有)只会移动一次,因此算法的时间复杂度为O(n),空间复杂度为O(1)。

类似题目:有两个有序的数组A1和A2,内存在A1的末尾有足够的空余空间容纳A2。实现一个函数,把A2中所有数字插入A1中,并且所有的数字是有序的。

思路:此时同样可以知道合并后数组的结束位置,建立指针newEnd指向结束位置,从后往前扫描A1和A2,比较后将较大的元素移动到newEnd处。

代码(含测试用例):

public class Q5plus{

public static void main(String[] args){

Q5plus p = new Q5plus();
p.test1();
p.test2();
p.test3();
}

// length1 is the the number of elements in the nums1
public void merge(int[] nums1, int[] nums2, int length1){

//robust
if(nums1 == null || nums2 == null || length1 <= 0)
System.out.println("null array");

int len2 = nums2.length;

// newEnd point to the end of the new merged sequence
int newEnd = length1 + len2 - 1;

int index1 = length1 - 1;
int index2 = len2 - 1;

while(index1 >= 0 && index2 >= 0){
if(nums1[index1] == nums2[index2]){
nums1[newEnd--] = nums1[index1--];
nums1[newEnd--] = nums2[index2--];
}
else if(nums1[index1] < nums2[index2]){
nums1[newEnd--] = nums2[index2--];
}
else
nums1[newEnd--] = nums1[index1--];
}

if(index2 >= 0)
while(index2 >= 0)
nums1[newEnd--] = nums2[index2--];
}

// no duplicate and index2 first decrease to 0
public void test1(){
int[] nums1 = new int[50];

for(int i = 0; i < 20; i++)
nums1[i] = i;

int[] nums2 = new int[10];
for(int i = 0; i < 10; i++)
nums2[i] = i + 20;

merge(nums1, nums2, 20);
for(int i = 0; i < nums1.length; i++)
System.out.printf("%d ", nums1[i]);
System.out.println();
}

// has duplicate
public void test2(){
int[] nums1 = new int[50];

for(int i = 0; i < 20; i++)
nums1[i] = i;

int[] nums2 = new int[10];
for(int i = 0; i < 10; i++)
nums2[i] = i + 2;

merge(nums1, nums2, 20);
for(int i = 0; i < nums1.length; i++)
System.out.printf("%d ", nums1[i]);
System.out.println();
}

// index1 first decrease to 0
public void test3(){
int[] nums1 = new int[50];

for(int i = 0; i < 10; i++)
nums1[i] = i + 10;

int[] nums2 = new int[10];
for(int i = 0; i < 10; i++)
nums2[i] = i;

merge(nums1, nums2, 10);
for(int i = 0; i < nums1.length; i++)
System.out.printf("%d ", nums1[i]);
System.out.println();
}

}


性能:

时间复杂度O(n),空间复杂度O(1)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: