微软算法100题88 将字符串中的字符'*'移到串的前部分
函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。如原始串为:ab**cd**e*12,处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)
思路:类似于快速排序,用两个指针分别指向字符数组的左右边界,寻找左边第一个不为*的字符,寻找右边第一个*,然后交换字符,然后继续寻找和交换的过程,直到两个指针相交, 时间复杂度o(n), 空间复杂度o(1)
第一个写的程序有问题,没有考虑到保持原有顺序的要求。。。
1 package com.rui.microsoft; 2 3 //字符串中的字符'*'移到串的前部分,前面的非'*'字符后移 4 public class Test88_MoveStar { 5 6 public static void main(String[] args) { 7 char[] a = "*ab**1*23*".toCharArray(); 8 Test88_MoveStar app = new Test88_MoveStar(); 9 app.move(a); 10 for(char t: a){ 11 System.out.print(t); 12 } 13 } 14 15 void move(char[] a){ 16 int left = 0; 17 int right = a.length - 1; 18 while(true){ 19 while(a[left] == '*' && left < a.length-1){ 20 left++; 21 } 22 23 while(a[right] != '*' && right > 0){ 24 right--; 25 } 26 27 if(left >= right) break; 28 swap(a,left,right); 29 } 30 } 31 32 void swap(char[] a, int i, int j){ 33 char tmp = a[i]; 34 a[i] = a[j]; 35 a[j] = tmp; 36 } 37 }
再写一个 可以保持原有非*字符的顺序
1 package com.rui.microsoft; 2 3 //字符串中的字符'*'移到串的前部分,前面的非'*'字符后移 4 public class Test88_MoveStar { 5 6 public static void main(String[] args) { 7 char[] a = "*ab**1*23*".toCharArray(); 8 Test88_MoveStar app = new Test88_MoveStar(); 9 int total = app.moveAndKeepSeq(a); 10 System.out.println("total: " + total); 11 for(char t: a){ 12 System.out.print(t); 13 } 14 } 15 16 int moveAndKeepSeq(char[] a){ 17 int i = a.length -1; 18 int j = a.length -1; 19 int count = 0; 20 while(i>=0){ 21 if(a[i] == '*'){ 22 i--; 23 count++; 24 }else{ 25 swap(a,i--,j--); 26 } 27 } 28 return count; 29 } 30 31 void swap(char[] a, int i, int j){ 32 char tmp = a[i]; 33 a[i] = a[j]; 34 a[j] = tmp; 35 } 36 }