算法通关村——字符串反转问题解析

字符串反转问题

我们知道反转是链表的一个重要考点,反转同样是字符串的重要问题。字符串和链表在处理反转的方式上有相似的地方,一般都是运用双指针,一个指针从前找,一个指针从后找。具体的处理办法结合下面具体的题目来看:

1、反转字符串

LeetCode344. 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间来解决这一问题。

示例:

输入:s = [“h”, “e”, “l”, “l”, “o”]

输出:[“o”, “l”, “l”, “e”, “h”]

这是最基本的反转问题,也是最简单的问题,使用双指针方法最直接。具体做法是:

  • 将left 指向字符数组首元素,right指向字符数组尾元素
  • 当left < right时:
    • 交换s[left] 和 s[right]
    • left指针向右移一位
    • right指针向左移一位
  • 当left>=right时,反转结束,返回字符数组

具体的java代码如下:

public void reverseString(char[] s) {if (s == null || s.length() == 0) {return;}int n = s.length;for (int left = 0, right = n - 1; left < right; left++, right++) {char temp = s[left];s[left] = s[right];s[right] = temp;}
}

2、K个一组反转

LeetCode541. 给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符。

  • 如果剩余字符少于k个,则将剩余字符全部反转。
  • 如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余字符保持原样。

示例1:

输入:s = “abcdefg”, k = 2

输出:“bacdfeg”

示例2:

输入:s = “abcd”, k = 2

输出:“bacd”

对于这题,只用按照题意来就好了:反转每个下标从2k的倍数开始的,长度为k的子串。若该子串长度不足k,则反转整个子串。

public String reverseStr(String s, int k) {if (s == null || s.length() == 0) {return s;}int n = s.length();char[] arr = s.toCharArray();for (int i = 0; i < n; i += 2 * k) {reverse(arr, i, Math.min(i + k, n) - 1);}return new String(arr);
}public void reverse(char[] arr, int left, int right) {while (left < right) {char temp = arr[left];arr[left] = arr[right];arr[right] = temp;left++;right--;}
}

3、仅仅反转字母

LeetCode917. 给定一个字符串S,返回”反转后的”字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。

示例1:

输入:“ab-cd”

输出:“dc-ab”

示例2:

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

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

示例3:

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

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

这题的难点主要在需要反转的段的划分不均匀,也就是非字母的字符出现在字符串中的位置是随机的。可以考虑用以下两种方法来做:

方法1:使用栈

将s中的所有字母单独存入栈中,所以出栈等价于对字母反序操作。然后,遍历s的所有字符,如果是字母我们就选择栈顶元素输出,不是字母就输出s的字符。代码如下:

public String reverseOnlyLetters(String s) {Stack<Character> letters = new Stack();for (char c : S.toCharArray()) {if (Character.isLetter(c)){letters.push(c);}}StringBuilder ans = new StringBuilder();for (char c :S.toCharArray()) {if (Character.isLetter(c)) {ans.append(letters.pop());} else {ans.append(c);}}return ans.toString();
}

方法2:拓展 双旋指针

一个接一个输出s的所有字符。当遇到一个字母时,我们希望找到逆序遍历字符串的下一个字母。所以我们可以维护一个指针j从后往前遍历字符串,当需要字母时就使用它。代码如下:

public String reverseOnlyLetters(String s) {if (s == null || s.length() == 0) {return s;}StringBuilder ans = new StringBuilder();int j = s.length() - 1;for (int i = 0; i < s.length(); i++) {if (Character.isLetter(s.chatAt(i))) {while (!Character.isLetter(s.char)){j--;}ans.append(s.charAt(j--));} else {ans.append(s.chatAt(i));}}return ans.toString();
}

4、反转字符串里的单词

LeetCode151. 给你一个字符串,逐个反转字符串中的所有 单词

单词是由非空格字符组成的字符串。s中至少一个空格将字符串中的单词分隔开。

请你返回一个反转s中单词顺序并用单个空格相连的字符串。

说明:

  • 输入字符串s可以在前面、后面或者单词间包含多余的空格。
  • 反转后的单词间应当仅用一个空格分隔。
  • 反转后的字符串中不应包含额外的空格。

示例:

输入:s = “the sky is blue”

输出:s = “blue is sky the”

在java语言中对字符串提供了split(拆分),reverse(反转)和join(连接)等方法,因此我们可以简单的调用内置的API来完成操作:

  • 使用split将字符串按空格分割成字符串数组
  • 使用reverse将字符串数组进行反转
  • 使用join方法将字符串数组拼成一个字符串

如图:

image-20231117222742177

public String reverseWords(String s) {if (s == null || s.length() == 0) {return s;}//除去开头和末尾的空白字符s = s.trim();//正则匹配连续的空白字符作为分隔符分割List<String> wordList = Arrays.asList(s.split("\\s+"));Collections.reverse(wordList);return String.join(" ", wordList);
}

如果不使用语言自己的提供的方法,也可以完成这一题。

方法流程如下:

image-20231117223155604

代码如下:

public static String reverseWords(String s) {StringBuilder sb = trimSpaces(s);// 翻转字符串reverse(sb, 0, sb.length() - 1);// 翻转每个单词reverseEachWord(sb);return sb.toString();
}public static StringBuilder trimSpaces(String s) {int left = 0, right = s.length() - 1;// 去掉字符串开头的空白字符while (left <= right && s.charAt(left) == ' ') {++left;}// 去掉字符串末尾的空白字符while (left <= right && s.charAt(right) == ' ') {--right;}// 将字符串间多余的空白字符去除StringBuilder sb = new StringBuilder();while (left <= right) {char c = s.charAt(left);if (c != ' ') {sb.append(c);} else if (sb.charAt(sb.length() - 1) != ' ') {sb.append(c);}++left;}return sb;
}public static void reverse(StringBuilder sb, int left, int right) {while (left < right) {char tmp = sb.charAt(left);sb.setCharAt(left++, sb.charAt(right));sb.setCharAt(right--, tmp);}
}public static void reverseEachWord(StringBuilder sb) {int n = sb.length();int start = 0, end = 0;while (start < n) {// 循环至单词的末尾while (end < n && sb.charAt(end) != ' ') {++end;}// 翻转单词reverse(sb, start, end - 1);// 更新start,去找下一个单词start = end + 1;++end;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/199549.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10-19 HttpServletResponse

相应的对象 web开发模型&#xff1a;基于请求与相应的模型 一问一答的模型 Response对象:响应对象,封装服务器给客户端的相关的信息 顶级接口: ServletResponse 父接口:HttpServletResponse response对象的功能分为以下四种:(都是服务器干的事注意) 设置响应头信息; 发送状态码…

关于WhatsApp群发营销价值、类型、优劣势……这里一次性讲清楚

01 社交销售互动&#xff1a;全球营销新趋势 当下&#xff0c;全球品牌的营销销售互动都步入了社交销售新时代&#xff0c;相比原来任何一种形式的互动沟通来说&#xff0c;其沟通效率、体验、效果都是无与伦比的。 企业与销售的互动&#xff0c;与通讯信息技术发展息息相关。…

手撕单链表(C语言)

目录 1.单链表的物理结构 2.头文件的实现 3.SList.c文件的实现 3.1尾插、创建节点 3.2打印 3.3头插 3.4尾删 3.5头删 3.6查找 3.7指定位置之前插入数据 3.8指定位置之后插入数据 3.9删除指定位置节点 3.10删除pos之后的节点 3.11销毁链表 4 所有的代码 1.单链表的物理结构 众所…

百分点科技|怎样做数据运营,才能让数据中台真正用起来?

导读&#xff1a;大多数企业用户已完成数据平台初步建设工作&#xff0c;但数据在业务运营和管理中没有发挥应有价值。数据开发工作繁重&#xff0c;数据质量问题严重&#xff0c;IT、数据和业务协作不畅&#xff0c;诸多问题依然困扰着企业用户的IT部门和数据部门。数据运营成…

Spring注解开发

注解开发 注解开发定义bean 使用Component定义bean 核心配置文件中通过组件扫描加载bean Spring提供Component注解的三个衍生注解 Controller&#xff1a;用于表现层bean定义Service&#xff1a;用于业务层bean定义Repository&#xff1a;用于数据层bean定义 纯注解开发 Spr…

在VSCode创建vue项目,出现“因为在此系统上禁止运行脚本”问题

问题&#xff1a;vue : 无法加载文件 C:\Users\***\***\Roaming\npm\vue.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 ht tps:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在位置 行:1 字符: 1 解决&#xff…

Ubuntu——卸载、安装CUDA

【注】WSL的Ubuntu是不用安装CUDA的&#xff0c;因为它使用的是Windows的显卡驱动&#xff0c;所以如果WSL的CUDA出了问题&#xff0c;重新安装WSL即可&#xff01; 如果nvidia-smi有显示&#xff0c;只是需要使用nvcc&#xff0c;那么就需要安装。安装的时候不要选Driver即可…

Android Termux安装MySQL,内网穿透实现公网远程访问

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…

会议剪影 | 思腾合力受邀出席第四届长三角文博会并作主题演讲

以“担当新使命:长三角文化产业的力量”为主题的「第四届长三角国际文化产业博览会」于2023年11月16日-19日在国家会展中心&#xff08;上海&#xff09;成功举办。思腾合力作为行业领先的人工智能基础架构解决方案商出席本次盛会。 此次展会的面积首次超过10万平米&#xff0c…

Python如何将项目直接打包为一键整合包

目录 一、准备项目 二、创建打包文件 三、创建安装脚本 四、执行安装 五、测试安装 六、常见问题与解决方案 总结 Python项目打包成一键整合包是一个比较复杂的任务&#xff0c;需要考虑到项目的各个方面&#xff0c;包括依赖项、配置文件、静态文件、数据库等等。下面是…

[C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

基于安卓android微信小程序的好物分享系统

运行环境 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&a…

提升工作效率,使用AnyTXT Searcher实现远程办公速查公司电脑文件——“cpolar内网穿透”

文章目录 前言1. AnyTXT Searcher1.1 下载安装AnyTXT Searcher 2. 下载安装注册cpolar3. AnyTXT Searcher设置和操作3.1 AnyTXT结合cpolar—公网访问搜索神器3.2 公网访问测试 4. 固定连接公网地址 前言 你是否遇到过这种情况&#xff0c;异地办公或者不在公司&#xff0c;想找…

短视频账号矩阵系统源码

短视频账号矩阵系统源码搭建步骤包括以下几个方面&#xff1a; 1. 确定账号类型和目标受众&#xff1a;确定要运营的短视频账号类型&#xff0c;如搞笑、美食、美妆等&#xff0c;并明确目标受众和定位。 2. 准备账号资料&#xff1a;准备相关资质和资料&#xff0c;如营业执照…

关于爬虫中的hook(defineProperty,hook cookies, hook载荷数据,hookXHR)

关于爬虫中的hook&#xff1a; defineProperty var people {age: 19, }; var count20; console.log(people.age) // 参数&#xff1a;对象 属性名字 函数 Object.defineProperty(people, age, {get: function () {console.log(获取值&#xff01;);return count;},// set: …

前端本地存储数据库IndexedDB

前端本地存储数据库IndexedDB 1、前言2、什么是 indexedDB&#xff1f;3、什么是 localForage&#xff1f;4、localForage 的使用5、VUE 推荐使用 Pinia 管理 localForage 1、前言 前端本地化存储算是一个老生常谈的话题了&#xff0c;我们对于 cookies、Web Storage&#xff…

酷开科技丨这么好用的酷开系统,不用真的会后悔!

掀开一幕幕精彩剧情&#xff0c;手机已经成为了我们身边必不可少的追剧神器。在这个信息爆炸的时代&#xff0c;我们渴望能够随时随地享受到精彩的影视作品&#xff0c;尤其是在家的休息的时候&#xff0c;希望电视也能同手机一样&#xff0c;想看啥就搜啥。酷开科技大内容战略…

django理解02 前后端分离中的问题

前后端分离相对于传统方式的问题 前后端数据交换的问题跨域问题 页面js往自身程序&#xff08;django服务&#xff09;发送请求&#xff0c;这是浏览器默认接受响应 而请求其它地方是浏览器认为存在潜在危险。自动隔离请求&#xff01;&#xff01;&#xff01; 跨域问题的解决…

根据nginx日志统计页面访问次数

静态页面部署在nginx上&#xff0c;页面只有查看下载功能。 需求是统计每条访问次数和下载次数&#xff0c;根据日志分析写了一个shell脚本&#xff0c;触发脚本后生成一个html可以远程查看统计的数量。 #!/bin/bash # nginx日志文件路径 LOG_FILE"/usr/local/nginx/l…