LeetCode 344.反转字符串,541. 反转字符串II,剑指Offer 05.替换空格,151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串

本文主要是介绍LeetCode 344.反转字符串,541. 反转字符串II,剑指Offer 05.替换空格,151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

344.反转字符串


因为字符串也是一种数组,所以元素在内存中是连续分布

题目链接:https://leetcode.cn/problems/reverse-string/

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:输入:["h","e","l","l","o"]输出:["o","l","l","e","h"]

示例 2:输入:["H","a","n","n","a","h"]输出:["h","a","n","n","a","H"]

头尾双指针法

相当于交换数组元素操作
class Solution {public void reverseString(char[] s) {int i = 0;int j =  s.length - 1;while(i < j){char temp = s[i];//注意是用字符接收s[i] = s[j];s[j] = temp;i++;j--;}}
}

541. 反转字符串II


这个反转要仔细读题

题目链接:https://leetcode.cn/problems/reverse-string-ii/

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

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。

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

示例:

输入: s = "abcdefg", k = 2输出: "bacdfeg"

class Solution {public String reverseStr(String s, int k) {char[] ch = s.toCharArray();for(int i = 0; i < ch.length; i += 2 * k){int start = i;int end = Math.min(ch.length - 1, start + k - 1);//这步的ch.length-1将条件1考虑到了,start+k-1考虑到了第二个条件,相当的巧妙while(start < end){char temp = ch[start];ch[start] = ch[end];ch[end] = temp;start++;end--;}}return new String(ch);}
}
思路:
首先将字符串转化为字符数组
解题关键:定义首尾指针,这里尾指针很关键
int end = Math.min(ch.length - 1, start + k - 1);//这步的ch.length-1将条件1考虑到了,start+k-1考虑到了第二个条件,相当的巧妙

剑指Offer 05.替换空格


题目链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1: 输入:s = "We are happy."输出:"We%20are%20happy."

StringBuilder方法

思路:使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
class Solution {public String replaceSpace(String s) {if(s == null){//不需要判断因为下面循环已经判断了,不满足条件直接就输出了return null;}StringBuilder sb = new StringBuilder();//可变对象for(int i = 0; i < s.length(); i++){if(s.charAt(i) == ' '){sb.append("%20");}else{sb.append(s.charAt(i));}}return sb.toString();}
}
注意:charAt()获取到的是字符,不是字符串
思考:为什么不用这个思路呢:先把字符串根据空格拆分形成字符串数组,之后再遍历字符串数组,遇到空格进行append;
上述步骤出问题在charAt这,因为charAt这取不到字符串数组中的单个字符串,所以上面方法不能成立。
class Solution {public String replaceSpace(String s) {if(s == null || s.length() == 0){//要判断s的长度,因为用到了双指针return s;}StringBuilder str = new StringBuilder();for(int i = 0; i < s.length(); i++){if(s.charAt(i) == ' '){str.append("  ");//}}if(str.length() == 0){return s;}//有空格的情况int left = s.length() - 1;s += str.toString();int right = s.length() - 1;char[] c = s.toCharArray();while(left >= 0){if(c[left] != ' '){c[right] = c[left];}else{c[right--] = '0';c[right--] = '2';c[right] = '%';}left--;right--;}return new String(c);}
}

官方解答

思路:很好,巧妙运用了new String(array,起始,结束)
class Solution {public String replaceSpace(String s) {int len = s.length();char[] ch = new char[3 * len];int size = 0;for(int i = 0; i < len; i++){if(s.charAt(i) == ' '){ch[size++] = '%';ch[size++] = '2';ch[size++] = '0';}else{ch[size++] = s.charAt(i);}}return new String(ch,0,size);}
}
String newStr = new String(array, 0, size);//其作用是将array函数从0到size由数组变成字符串,左闭右开

151.翻转字符串里的单词


全面考察字符串的操作,重点看 方法二 对之后的代码书写细节会有一个提高
部分细节说明
StringBuilder 中有reverse()方法,并且包含了首位位置,但StringBuilder s = s1.reverse();只能将整体反转,不能指定起始位置split() 可以引入正则表达式public void reverse(StringBuilder sb, int left, int right) {while (left < right) {char tmp = sb.charAt(left);//主要是用来替换的,方法里面有两个参数 setCharAt(int index,Char ch)//第一个参数是取代的位置 索引从0开始 第二个参数是你要替换为的字符串sb.setCharAt(left++, sb.charAt(right));sb.setCharAt(right--, tmp);}}

题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:输入: "the sky is blue"输出: "blue is sky the"

示例 2:输入: " hello world! "输出: "world! hello"解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:输入: "a good example"输出: "example good a"解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

用API

class Solution {public String reverseWords(String s) {//去除字符串的首位字符String s1 = s.trim();//将字符串中的一个或多个空格进行拆分String[] s2 = s1.split(" +");StringBuilder s3 = new StringBuilder();for(int i = s2.length - 1; i >= 0; i--){s3.append(s2[i] + ' ');}return s3.toString().trim();}
}

方法二

不使用Java内置方法实现* 1.去除首尾以及中间多余空格* 2.反转整个字符串* 3.反转各个单词
  • 官方答案,已经注释的很清晰了

class Solution {public String reverseWords(String s) {StringBuilder sb = trimSpaces(s);
​// 翻转字符串reverse(sb, 0, sb.length() - 1);
​// 翻转每个单词reverseEachWord(sb);
​return sb.toString();}
​public 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);} //如果为空格 但是sb中最后一个不是空格也加入进去 (这样就将多个空格变成了一个空格)else if (sb.charAt(sb.length() - 1) != ' ') {sb.append(c);}
​++left;}return sb;}
​//将字符串进行反转 a good example就反转成 elpmaxe doog apublic void reverse(StringBuilder sb, int left, int right) {while (left < right) {char tmp = sb.charAt(left);//主要是用来替换的,方法里面有两个参数 setCharAt(int index,Char ch)//第一个参数是取代的位置 索引从0开始 第二个参数是你要替换为的字符串sb.setCharAt(left++, sb.charAt(right));sb.setCharAt(right--, tmp);}}
​//这个主要是将elpmaxe doog a 变成 example good apublic void reverseEachWord(StringBuilder sb) {int n = sb.length();int start = 0, end = 0;
​while (start < n) {// 循环至单词的末尾while (end < n && sb.charAt(end) != ' ') {//注意end < n 一定放在前面判断++end;}// 翻转单词reverse(sb, start, end - 1);//这里调用的是自己的reverse方法,注意是end - 1// 更新start,去找下一个单词start = end + 1;++end;}}
}

剑指Offer58-II.左旋转字符串


String 的API substring截取之后,原字符串本身并没有变

题目链接:https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:输入: s = "abcdefg", k = 2输出: "cdefgab"

示例 2:输入: s = "lrloseumgh", k = 6输出: "umghlrlose"

限制:1 <= k < s.length <= 10000

常规拼接方法

  • 方法一

class Solution {public String reverseLeftWords(String s, int n) {StringBuilder str = new StringBuilder();for(int i = n ; i < s.length(); i++){str.append(s.charAt(i));}for(int i = 0; i < n; i++){str.append(s.charAt(i));}return str.toString();       }
}
  • 方法二

class Solution {public String reverseLeftWords(String s, int n) {String s1 = s.substring(0,n);String s2 = s.substring(n);return s2 + s1;}
}

先局部反转再 整体反转

先把左面字符串反转,在反转右面,在整体反转,注意:反转的次序不要错
  • 方法一:利用数组进行交换

class Solution {public String reverseLeftWords(String s, int n) {char[] c = s.toCharArray();reverse(c, 0, n - 1);reverse(c, n, c.length - 1);reverse(c, 0,c.length - 1);return new String(c);}public void reverse(char[] c, int left, int right){while(left < right){char temp = c[left];c[left] = c[right];c[right] = temp;left++;right--;}}
}
  • 方法二

利用字符串进行交换

class Solution {public String reverseLeftWords(String s, int n) {StringBuilder str = new StringBuilder(s);int len = s.length();reverse(str, 0, n - 1);reverse(str, n, len - 1);reverse(str, 0, len - 1);return str.toString();}public void reverse(StringBuilder str, int left, int right){while(left < right){char temp = str.charAt(left);str.setCharAt(left++, str.charAt(right));str.setCharAt(right--, temp);}}
}

这篇关于LeetCode 344.反转字符串,541. 反转字符串II,剑指Offer 05.替换空格,151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/803466

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

poj 2187 凸包or旋转qia壳法

题意: 给n(50000)个点,求这些点与点之间距离最大的距离。 解析: 先求凸包然后暴力。 或者旋转卡壳大法。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <s

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk