面试题(五)替换空格
2018-02-01 20:00
309 查看
题目:实现一个函数,把字符串中的每个空格替换成“%20”。如输入“We are happy”,输出“We%20are%20happy”。
思路:
1. 可以从前到后扫描字符串,每遇到空格便将其后的元素往后移动两位,然后写入“%20”。这样会有元素被移动多次。算法的时间复杂度为O(n^2)。
2. 先扫描字符串得到字符串中空格的数量,再从后往前扫描字符串:设置两个指针,一个指针newEnd指向替换后字符串的尾部,一个指针originalEnd指向原字符串尾部(此处用字符数组表示字符串,并且字符数组的空间足够大)。若originalEnd指向的元素非空格,则进行元素移动,否则进行替换。当两个指针重合时,替换结束。
代码(含单元测试):
性能:
由于字符串中所有字符(或许没有所有)只会移动一次,因此算法的时间复杂度为O(n),空间复杂度为O(1)。
类似题目:有两个有序的数组A1和A2,内存在A1的末尾有足够的空余空间容纳A2。实现一个函数,把A2中所有数字插入A1中,并且所有的数字是有序的。
思路:此时同样可以知道合并后数组的结束位置,建立指针newEnd指向结束位置,从后往前扫描A1和A2,比较后将较大的元素移动到newEnd处。
代码(含测试用例):
性能:
时间复杂度O(n),空间复杂度O(1)
思路:
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)
相关文章推荐
- 《剑指offer》面试题4 替换空格为%20
- 面试题4:替换空格
- 剑指offer_面试题4_替换空格(注意时间效率)
- 剑指offer面试题4-- 替换空格
- 剑指offer面试题[4]-空格替换
- 剑指offer面试题4 替换空格(java)
- 剑指offer——面试题4:替换空格
- 《剑指Offer》学习笔记--面试题4:替换空格
- 剑指Offer算法题之字符串替换字符--面试题4:替换空格
- 《剑指offer面试题4》替换空格——实现函数把字符串中每个空格替换成“%20”
- 面试题4:替换字符串中的空格
- 面试题4:替换空格
- 剑指Offer,面试题4,替换空格,Java写法
- 面试题2:替换空格
- 面试题4:替换空格之发散思维
- 【剑指Offer面试题】 九度OJ1510:替换空格
- 面试题3:替换空格和清除空格
- 面试题四:替换空格
- [剑指offer]面试题4:替换空格
- 《剑指offer》面试题4 替换空格