思路:
题目的主要信息:
- 将字符串中数字为偶数的数字进行翻转,即翻转字符串,但只调换数字为偶数的位置
- 数字不包含0,字符串长度可能为0
方法一:暴力法
具体做法:
遍历字符串,用一个辅助数组顺序记录所有出现的偶数,再次遍历字符串,遇到偶数时,替换为辅助数组逆序中的字符。
class Solution { public: string change(string number) { string res = ""; vector<char> temp; int n = number.size(); if(n <= 1) //如果只有1位或者空,直接返回原串 return number; for(int i = 0; i < n; i++) if((number[i] - '0') % 2 == 0) //若为偶数记录下来 temp.push_back(number[i]); int m = temp.size() - 1; for(int i = 0; i < n; i++){ if((number[i] - '0') % 2 == 0) //若为偶数将后面的替换上来 res += temp[m--]; else res += number[i]; } return res; } };
复杂度分析:
- 时间复杂度:,两次遍历,每次都是
- 空间复杂度:,辅助数组temp长度为,其中最坏情况为,即每个都是偶数
方法二:双指针
具体做法:
设置一个从前往后的指针i和一个从后往前的指针j,两个指针分别找到后续第一个偶数及前序第一个偶数,如果此时两指针未相遇,则交换内容,继续分别向后向前搜索,直到两指针相遇。
class Solution { public: string change(string number) { int n = number.length(); if(n <= 1) return number;//如果只有1位或者空,直接返回原串 int i = 0; int j = n - 1; while(i < j){ //直到两个指针相遇,遍历结束 while(i < j && (number[i] - '0') % 2 != 0) //找到后续第一个偶数 i++; while(j > i && (number[j] - '0') % 2 != 0) //找到前续第一个偶数 j--; if(i < j){ char temp = number[i]; number[i] = number[j]; number[j] = temp; i++; j--; } } return number; } };
复杂度分析:
- 时间复杂度:,遍历半个字符串,即
- 空间复杂度:,常数个临时变量