这是网络流传的Microsoft的面试题目之一:“编写反转字符串的程序,要求优化速度、优化空间”。因为最近一直很多关注算法方面的实践和研究,因此对这个问题进行了一些思考,给出了5种实现方法(有两种解法相关性比较大)。
解法一:第一次看到这题目,想到最简单、最直觉的解法就是:遍历字符串,将第一个字符和最后一个交换,第二个和倒数第二个交换,依次循环,即可,于是有了第一个解法:
char* strrev1(const char* str)
{
int len = strlen(str);
char* tmp = new char[len + 1];
strcpy(tmp,str);
for (int i = 0; i < len/2; ++i)
{
char c = tmp[i];
tmp[i] = tmp[len – i - 1];
tmp[len – i - 1] = c;
}
return tmp;
}
|
这里是通过数组的下标方式访问字符串的字符,实际上用指针直接操作即可。解法二正是基于此,实现代码为:
char* strrev2(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
char t = *tmp;
*tmp = *p;
*p = t;
--p;
++tmp;
}
return ret;
}
|
显然上面的两个解法中没有考虑时间和空间的优化,一个典型的优化策略就是两个字符交换的算法优化,我们可以完全不使用任何外部变量即完成两个字符(或者整数)的交换,这也是一个很经典的面试题目。特别是一些嵌入式硬件相关编程中经常要考虑寄存器的使用,因此经常有不使用任何第三个寄存器即完成两个寄存器数据的交换的题目。一般有两个解法,对应这里的解法三和解法四。
解法三的实现代码为:
char* strrev3(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
*p ^= *tmp;
*tmp ^= *p;
*p ^= *tmp;
--p;
++tmp;
}
return ret;
}
|
解法四的实现代码为:
char* strrev4(const char* str)
{
char* tmp = new char[strlen(str) + 1];
strcpy(tmp,str);
char* ret = tmp;
char* p = tmp + strlen(str) - 1;
while (p > tmp)
{
*p = *p + *tmp;
*tmp = *p - *tmp;
*p = *p - *tmp;
--p;
++tmp;
}
return ret;
}
|
实际上我们还可以通过递归的思想来解决这个问题,思想很简单:每次交换首尾两个字符,中间部分则又变为和原来字符串同样的问题,因此可以通过递归的思想来解决这个问题,对应解法五的实现代码为:
char* strrev5(/*const */char* str,int len)
{
if (len <= 1)
return str;
char t = *str;
*str = *(str + len -1);
*(str + len -1) = t;
return (strrev5(str + 1,len - 2) - 1);
}
|
以下给出一个测试程序:
int main(int argc,char* argv[])
{
char* str = "hello";
P(str);
char* str2 = strrev1(str);
P(str2);
char* str3 = strrev2(str2);
P(str3);
char* str4 = strrev3(str3);
P(str4);
char* str5 = strrev4(str4);
P(str5);
char* str6 = strrev5(str5,strlen(str5));
P(str6);
return 0;
}
|
你就可以看到字符串"hello"和"olleh"交替输出了。
说明:1)这里解法中没有认真考虑输入字符串的合法性和特殊长度(如NULL、一个字符等)字符串的处理;2)前4个算法不改变输入字符串的值,解法五修改了输入字符串。
分享到:
相关推荐
java面试真题——江苏骏环昇旺科技.jpgjava面试真题——江苏骏环昇旺科技.jpgjava面试真题——江苏骏环昇旺科技.jpgjava面试真题——江苏骏环昇旺科技.jpgjava面试真题——江苏骏环昇旺科技.jpgjava面试真题——江苏...
最全面的java面试题——选择题部分
这是因为给出的文件信息中,标题为“银行面试真题——客户经理.pdf”,描述与标题相同,均为“银行面试真题——客户经理.pdf”,而标签部分为空。接着,您提供的部分内容是一串数字和符号,没有实际的文字内容,因此...
微软作为全球知名的科技巨头,其面试题历来备受关注,这些题目不仅体现了微软对技术人才的期望,也成为了求职者提升自身技能的重要参考资料。本压缩包中的“微软试题合集”涵盖了多个领域的技术问题,旨在测试候选人...
二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ / \ 4 8 12 16 ...
` 创建了两个对象: 一个字符串常量和一个`String`对象。 8. **Math.round 方法** - `Math.round(11.5)` 返回 12。 - `Math.round(-11.5)` 返回 -11。 - `Math.round` 方法通过加 0.5 后向下取整的方式计算最...
世界500强面试题——让你在面试时更有自信!
在这个"反转字符串"的面试题中,我们将深入探讨如何使用双指针来实现这一任务。 首先,我们需要了解C语言中字符串的基本概念。在C语言中,字符串是由零个或多个字符组成的序列,以空字符'\0'作为结束标志。我们通常...
01 java面试——北京-百度-Java中级.pdf 02 java面试——北京-京东-Java中级.pdf 03 java面试——广州-唯品会-Java大数据开发工程师.pdf 04 java面试——杭州-阿里云-Java中级.pdf 05 java面试——杭州-蚂蚁金服-...
HCIE 面试题——LAN&WAN 技术 HCIE 面试题——LAN&WAN 技术是一份关于 LAN&WAN 技术的面试题,涵盖了交换机端口类型、VLAN 帧的识别、数据帧的处理方式等多个方面的知识点。 交换机端口类型 交换机端口类型有四种...
字符串处理面试题总结 字符串处理是程序员日常工作中最常遇到的问题,能够体现程序员的基本功。下面是关于字符串处理的面试题总结: 一、求字符串的最小后继 问题:实现一个函数,输入一个字符串,输出该字符串的...
广西教师结构化面试题——自我认知类.pdf
"网络工程师面试题——CCNA" 本文主要讨论了三层交换机和路由器的区别、路由协议的分类、OSPF路由协议的操作过程和特点、RIP和OSPF协议的比较等知识点。 一、三层交换机和路由器的区别 三层交换机和路由器都是...
在Python编程语言中,...总之,LeetCode上的第344题“反转字符串”是一个经典的面试题,它测试了对字符串操作和双指针技巧的掌握。通过理解和实践这个题目,可以增强你的Python编程和算法能力,对于准备面试大有裨益。
UC面试题,里面包含uc经典面试题,是准备找uc工作的人的首选。
本面试题的核心是使用双指针技巧来反转字符串中的单词,这是一个常见的编程挑战,旨在考察候选人的逻辑思维和对C语言基础知识的掌握程度。 首先,我们需要理解题目要求。反转字符串中的单词意味着保持每个单词的...
微软公司面试人员的面试题解答,google微软等大公司面试题,软件架构师的设计。
【标题】:“面试题——银行业务调度系统-源代码”涉及的是一个基于JavaSE的银行后台管理系统,旨在处理银行日常的业务调度问题。这个系统可能是为了模拟或优化银行内部的工作流程,例如账户管理、交易处理、客户...
这份“软件测试面试题——超全面”资源包含了各大公司可能会问到的各种问题,既涵盖了技术层面,也涉及了人力资源管理方面。这样的全面准备对求职者来说至关重要,因为它可以帮助他们更好地理解测试工程师的角色以及...