package LeetCode.stringpart01;
/**
* 344. 反转字符串
* 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
* 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
* 示例:
* 输入:s = ["h","e","l","l","o"]
* 输出:["o","l","l","e","h"]
* */
/**
* 双指针
* */
public class ReverseString_344 {
public static void main(String[] args) {
char [] c = {'h','e','l','l','o'};
reverseString(c);
System.out.println(c);
}
public static void reverseString(char[] s) {
int l = 0;
int r = s.length - 1;
while(l < r){
char temp = s[l];
s[l] = s[r];
s[r] = temp;
l++;
r--;
}
}
}
package LeetCode.stringpart01;
/**
* 541. 反转字符串 II
* 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
* 如果剩余字符少于 k 个,则将剩余字符全部反转。
* 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
* 示例:
* 输入:s = "abcdefg", k = 2
* 输出:"bacdfeg"
* */
/**
* 每隔2k个反转前k个,尾数不够k个时候全部反转
* */
public class ReverseStringII_541 {
public static void main(String[] args) {
String str = "abcdefg";
int k = 2;
String result = reverseStr(str,k);
System.out.println(result);
}
public static String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
// 1. 每隔 2k 个字符的前 k 个字符进行反转
for (int i = 0; i< ch.length; i += 2 * k) {
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= ch.length) {
reverse(ch, i, i + k -1);
continue;
}
// 3. 剩余字符少于 k 个,则将剩余字符全部反转
reverse(ch, i, ch.length - 1);
}
return new String(ch);
}
// 定义翻转函数
public static void reverse(char[] ch, int i, int j) {
for (; i < j; i++, j--) {
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
}
}
}
package LeetCode.stringpart01;
/**
* 剑指 Offer 05. 替换空格
* 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
* 示例:
* 输入:s = "We are happy."
* 输出:"We%20are%20happy."
* */
public class ReplaceSpace_offer05 {
public static void main(String[] args) {
String str = "We are happy.";
String result = replaceSpace(str);
System.out.println(result);
}
public static String replaceSpace(String s) {
if (s == null) {
return null;
}
//选用 StringBuilder 单线程使用,比较快,选不选都行
StringBuilder sb = new StringBuilder();
//使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
for (int i = 0; i < s.length(); i++) {
//s.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
//if (" ".equals(String.valueOf(s.charAt(i)))){}
if (s.charAt(i) == ' ') {
sb.append("%20");
} else {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}
package LeetCode.stringpart01;
/**
* 541. 反转字符串 II
* 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
* 如果剩余字符少于 k 个,则将剩余字符全部反转。
* 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
* 示例:
* 输入:s = "abcdefg", k = 2
* 输出:"bacdfeg"
* */
/**
* 每隔2k个反转前k个,尾数不够k个时候全部反转
* */
public class ReverseStringII_541 {
public static void main(String[] args) {
String str = "abcdefg";
int k = 2;
String result = reverseStr(str,k);
System.out.println(result);
}
public static String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
// 1. 每隔 2k 个字符的前 k 个字符进行反转
for (int i = 0; i< ch.length; i += 2 * k) {
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= ch.length) {
reverse(ch, i, i + k -1);
continue;
}
// 3. 剩余字符少于 k 个,则将剩余字符全部反转
reverse(ch, i, ch.length - 1);
}
return new String(ch);
}
// 定义翻转函数
public static void reverse(char[] ch, int i, int j) {
for (; i < j; i++, j--) {
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
}
}
}
package LeetCode.stringpart01;
/**
* 剑指 Offer 58 - II. 左旋转字符串
* 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。
* 比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
* 示例:
* 输入: s = "abcdefg", k = 2
* 输出: "cdefgab"
* */
/**
* 思路:
* 1.反转区间为前n的子串
* 2.反转区间为n到末尾的子串
* 3.反转整个字符串
* */
public class ReverseLeftWords_offer58 {
public static void main(String[] args) {
String s = "abcdefg";
int k = 2;
String result = reverseLeftWords(s,k);
System.out.println(result);
}
public static String reverseLeftWords(String s, int n) {
int len=s.length();
StringBuilder sb=new StringBuilder(s);
reverseString(sb,0,n-1);
reverseString(sb,n,len-1);
return sb.reverse().toString();
}
public static void reverseString(StringBuilder sb, int start, int end) {
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
}
}