一道有趣的面试题
2013-05-07 22:13
337 查看
题目大意:给你一个由小写字母和*符号组成的字符串,要求你把其中的*符号全部转移到字符串的首部,而其他字母的相对序列保持不变,如*af*dxc*aa*转换成****afdxcaa。要求时间复杂度和空间复杂度尽量小。(其实这个问题还有好多变种,比如将一个字符串的大写字母转移到字符串前面或后面,将一个数组中的奇数和偶数区分开来,前半部分为偶数后半部分为奇数等等)
思路:这里介绍一个时间复杂度为O(n),空间复杂度为O(1)的方法。我们设两个变量,x表示最右边的*符号的位置,y表示在x左边的最右边的小写字母的位置。那么首先从右到左将第一个x和y求出来,然后交换两个位置的字符,交换之后继续从右到左更新x和y的值,当x或y小于0时退出,这个算法空间复杂度显然为O(1),下面来看时间复杂度,由于x和y一直是递减的,从n-1减到0为止,所以时间复杂度为O(n)。至于算法为什么是正确的,自己推一下就明白了,这道题还是看得蛮多的,好多公司面试都有,还有好多变种,但是思想是相同的。详细实现请看代码:
代码如下:
思路:这里介绍一个时间复杂度为O(n),空间复杂度为O(1)的方法。我们设两个变量,x表示最右边的*符号的位置,y表示在x左边的最右边的小写字母的位置。那么首先从右到左将第一个x和y求出来,然后交换两个位置的字符,交换之后继续从右到左更新x和y的值,当x或y小于0时退出,这个算法空间复杂度显然为O(1),下面来看时间复杂度,由于x和y一直是递减的,从n-1减到0为止,所以时间复杂度为O(n)。至于算法为什么是正确的,自己推一下就明白了,这道题还是看得蛮多的,好多公司面试都有,还有好多变种,但是思想是相同的。详细实现请看代码:
代码如下:
#include <stdio.h> #include <string.h> #define maxn 110 void solve(char *str) { int len=strlen(str),x,y; x=len-1; while(x>=0&&str[x]!='*') x--; y=x-1; while(y>=0&&str[y]=='*') y--; while(x>=0&&y>=0) { str[x]=str[x]^str[y]; str[y]=str[x]^str[y]; str[x]=str[x]^str[y]; //以上是交换两个字符 while(x>=0&&str[x]!='*') x--; while(y>=0&&str[y]=='*') y--; } } int main() { char str[maxn]; scanf("%s",str); solve(str); printf("%s\n",str); return 0; }
相关文章推荐
- 【算法】一道有趣的GOOGLE面试题
- 一道有趣的GOOGLE面试题 .
- 白话经典算法系列之十 一道有趣的GOOGLE面试题
- 白话经典算法系列之十 一道有趣的GOOGLE面试题
- 【算法】一道有趣的GOOGLE面试题 --【解法2】
- 一道有趣的面试题
- 一道有趣的面试题
- 白话经典算法系列之十一 一道有趣的GOOGLE面试题 【解法2】
- 一道有趣的面试题和相关知识补充
- 一道有趣的C#面试题
- 一道有趣的面试题
- 【白话经典算法系列之十】 一道有趣的GOOGLE面试题
- 一道有趣的面试题
- 《一道有趣的面试题》的疑问
- 一道有趣的GOOGLE面试题——找出至少一个重复元素
- 一道有趣的面试题 - 设计模式的运用
- 一道有趣的面试题————待解决的问题
- 一道有趣的面试题
- 【白话经典算法系列之十一】一道有趣的GOOGLE面试题 --【解法2】
- 白话经典算法系列之十 一道有趣的GOOGLE面试题