字符串反转是面试过程中出现频率较高的算法题,今天一个牛同事让我用C#帮他实现这个算法,前提当然是不能使用类库。
例如: how are you 的反转结果为 you are how.
算法1: 是我当场写的一个不太理想的算法,虽然不太理想,但思路很直接:
1. 申请一个新的字符数组,新字符数组大小与源字符串等长度。
2. 将源字符串从末尾向前端进行遍历。将每一个单词加入新字符数组。
使用变量count记录当前单词长度。即,
若字符非空格,count++;
若字符是空格,则将原数组从当前位置开始的count个字符加入到新数组中。
static void Main(string[] args) { string testString = "how are you"; var result = reverseString(testString); } static char[] reverseString(string value) { if (string.IsNullOrEmpty(value)) return new char[] { }; int length = value.Length; char[] result = new char[length]; int count = 0; int rIndex = 0; for (int i = length-1; i>=0; i--) { if(value[i]!=' ') { count++; } if(value[i]==' ') { int index = i + 1; for(; index< i+count+1; index++) { result[rIndex++] = value[index]; } count = 0; result[rIndex++] = ' '; } } // fot the first word foreach (char c in value) { if (c != ' ') result[rIndex++] = c; else break; } return result; } }
算法2: 今天下班前,又花了1个小时重新考虑了这个问题,其实要实现空间开销最小,时间复杂度最低,可以实现一个字符数组反转程序。 思路如下:
1. 先将整个元字符数组反转, 得到 uoy era woh.
2. 再将每个单词进行反转, 同样使用空字符分割单词。
注意:字符数组反转函数,1. 不需要遍历所有字符,仅仅遍历二分之一的字符即可。 2. 用left, right控制字符数组中反转字符的起始位置。
namespace reverseWords { /// <summary> /// Qijie Xue /// </summary> class Program { static void Main(string[] args) { string testData = "how are you now"; var result = reverseString2(testData); } static char[] reverseString2(string value) { char[] ochr = value.Trim().ToString().ToArray(); ochr = reverseChar(ref ochr, 0, ochr.Length - 1); int start = 0; int end = 0; for(int i = 0; i<ochr.Length; i++) { if(ochr[i]==' ') { end = i - 1; reverseChar(ref ochr, start, end); start = i + 1; } if(i==ochr.Length - 1) { end = ochr.Length - 1; reverseChar(ref ochr, start, end); } } return ochr; } static char[] reverseChar(ref char[] ochr, int left, int right) { int mid = (right + left) >> 1; int l = 0; int r = 0; //even numbers, l = mid, r = mid + 1 //odd numbers, l = mid - 1, r = mid + 1 if ((right - left + 1) % 2 == 0) { l = mid + 1; r = mid; } else { l = r = mid; } while (l > left) { l--; r++; char tchr = ochr[l]; ochr[l] = ochr[r]; ochr[r] = tchr; } return ochr; } } }
以上两种算法,都需要将源字符串两端的空字符去掉。