这是悦乐书的第353次更新,第378篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第215题(顺位题号是917)。给定一个字符串S,返回“反向”字符串,其中所有非字母的字符都保留在同一位置,并且所有字母都反转其位置。例如:

输入:“ab-cd”

输出:“dc-ba”

输入:“a-bC-dEf-ghIj”

输出:“j-Ih-gfE-dCba”

输入:“Test1ng-Leet = code-Q!”

输出:“Qedo1ct-eeLg = ntse-T!”

注意

  • S.length <= 100

  • 33 <= S[i].ASCIIcode <= 122

  • S不包含\

02 第一种解法

使用双指针

定义两个指针ij,一个从前往后,一个从后往前,只有两个指针所在元素都是字母时才交换位置,如果其中一个不是字母,就向前前进一步继续判断,如果两个指针所在元素都不是字母就同时向前移动。

此解法的时间复杂度是O(N),空间复杂度是O(N)

public String reverseOnlyLetters(String S) {
int i = 0, j = S.length()-1;
char[] arr = S.toCharArray();
while (i < j) {
char c = arr[i];
char c2 = arr[j];
if (Character.isLetter(c) && Character.isLetter(c2)) {
arr[i] = c2;
arr[j] = c;
i++;
j--;
} else if (!Character.isLetter(c) && Character.isLetter(c2)) {
i++;
} else if (Character.isLetter(c) && !Character.isLetter(c2)) {
j--;
} else if (!Character.isLetter(c) && !Character.isLetter(c2)) {
i++;
j--;
}
}
return new String(arr);
}

03 第二种解法

在双指针的基础上做了下变动,使用StringBuilder来拼接新的字符,但是双指针的思路没变。

此解法的时间复杂度是O(N),空间复杂度是O(N)

public String reverseOnlyLetters2(String S) {
int j = S.length()-1, n = S.length();
StringBuilder sb = new StringBuilder();
for (int i=0; i<n; i++) {
if (Character.isLetter(S.charAt(i))) {
while (j>=0 && !Character.isLetter(S.charAt(j))) {
j--;
}
sb.append(S.charAt(j--));
} else {
sb.append(S.charAt(i));
}
}
return sb.toString();
}

04 第三种解法

利用栈,借助其先进后出的特性。

先将S中的字母全部入栈,然后再遍历S中的字符,如果是字母,就从栈顶取一位元素出来拼接,不是字母,就直接拼接当前元素。

此解法的时间复杂度是O(N),空间复杂度是O(N)

public String reverseOnlyLetters3(String S) {
Stack<Character> stack = new Stack<Character>();
char[] arr = S.toCharArray();
for (char c : arr) {
if (Character.isLetter(c)) {
stack.push(c);
}
}
StringBuilder sb = new StringBuilder();
for (char c : arr) {
if (Character.isLetter(c)) {
sb.append(stack.pop());
} else {
sb.append(c);
}
}
return sb.toString();
}

05 小结

算法专题目前已连续日更超过六个月,算法题文章221+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

最新文章

  1. js 基础篇(点击事件轮播图的实现)
  2. idea 插件的使用 进阶篇
  3. ASP.NET使用Razor语法无法正确识别.cshtml文件
  4. Linux线程-创建
  5. sublime 实用 快捷键
  6. 使用PHP输出中文JSON字符串
  7. Qt零基础教程(四) QWidget详解篇
  8. C++ 中 struct和class 的区别
  9. 201521145048《java程序与设计》第9周学习总结
  10. linux学习之路--(四)文件,目录管理
  11. node框架express
  12. wpf 寻找TreeView的子元素,并对其进行操作
  13. HTML学习笔记Day5
  14. bat 获取拖放文件路径或名称
  15. salt上编写了备份日志的脚本
  16. 24小时学通Linux内核之构建Linux内核
  17. c——根据天数输出日期
  18. 通过 Ansible 创建 Jenkins Server
  19. [转载]Oracle 游标使用全解
  20. mybatis实现一对多连接查询

热门文章

  1. vim简明教程(附快速记忆方法)
  2. Mysql 查看连接数,状态及最大并发数(转载)
  3. dlopen用法
  4. 【51nod1220】约数之和
  5. Redis常见面试问题及答案
  6. Redis 集群规范
  7. scrapy项目5:爬取ajax形式加载的数据,并用ImagePipeline保存图片
  8. Makefile文件试错
  9. unittest详解(七) 自动生成测试报告
  10. Python3学习笔记(十):赋值语句和布尔值