先来一道简单题:
将字符串左旋。输入abcdefg,输出cdefgab
package Leetcode;
/**
* @Author: YCKJ3803
* @Date: 2021/3/1 16:41
* @Description:
*/
public class Zuoxuan {
//直接用String的substring方法
public static String zuoXuan(String str, int n) {
return str.substring(n) + str.substring(0, n);
}
//使用StringBuilder的append方法,和String的charAt方法 StringBuilder线程不安全,效率高
public static String zuoXuan2(String str, int n) {
StringBuilder builder = new StringBuilder();
for (int i = n; i < str.length(); i++) {
builder.append(str.charAt(i));
}
for (int i = 0; i < n; i++) {
builder.append(str.charAt(i));
}
return builder.toString();
}
//如果只让用String,不让使用StringBuilder的话,怎么办?
public static String zuoXuan3(String str, int n) {
String res = "";
for (int i = n; i < str.length(); i++) {
res += str.charAt(i);
}
for (int i = 0; i < n; i++) {
res += str.charAt(i);
}
return res;
}
public static void main(String[] args) {
String str = "abcdefg";
System.out.println(zuoXuan(str, 2));
}
}
题意
题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
样例输入
student. a am I
I’m a Freshman and I like JOBDU!
样例输出
I am a student.
JOBDU! like I and Freshman a I’m
先反转整个字符串,再将每个单词内部翻转
先写一个reverse方法,将整个字符串都翻转一下,每次定义一个变量记录空白的位置,然后递归的使用reverse方法。
注:本题的i的变量,从后往前算。
package cn.com;
public class ReverseSentence {
public static void main(String[] args) {
String str = "I am a Student.";
System.out.println(ReverseSentence(str));
}
public static String ReverseSentence(String str) {
char[] chars = str.toCharArray();
reverse(chars,0,chars.length - 1);
int blank = -1;
for(int i = 0;i < chars.length;i++){
if(chars[i] == ' '){
int nextBlank = i;
reverse(chars,blank + 1,nextBlank - 1);
blank = nextBlank;
}
}
reverse(chars,blank + 1,chars.length - 1);//最后一个单词单独进行反转
return new String(chars);
}
public static String reverse(char[] chars,int low,int high){
while(low < high){
char temp = chars[low];
chars[low] = chars[high];
chars[high] = temp;
low++;
high--;
}
return chars.toString();
}
}
如果面试者一下子就回答出来了,面试官会怀疑你之前看过这道题,会问你一个更深入的题。如下,要是左旋字符串,怎么办?
将字符串前面的若干字符移到尾部。如输入“abcdefg”和数字2,表示将前2个字符移到后面。变成“cdefgab”。
思路:三次reverse,前两次将每个部分的内部翻转,为“bagfedc”,第三次整体翻转,变为“cdefgab”。
package cn.com;
/*
剑指offer-42-左旋转字符串
*/
public class LeftReverse {
public static void main(String[] args) {
String str = "abcdefg";
System.out.println(LeftReverse(str,2));
}
public static String LeftReverse(String str, int n) {
char[] chars = str.toCharArray();
if(chars.length < n) return "";
reverse(chars, 0, n-1);
reverse(chars, n, chars.length-1);
reverse(chars, 0, chars.length-1);
StringBuilder sb = new StringBuilder(chars.length);
for(char c:chars){
sb.append(c);
}
return sb.toString();
}
public static void reverse(char[] chars,int low,int high){
char temp;
while(low<high){
temp = chars[low];
chars[low] = chars[high];
chars[high] = temp;
low++;
high--;
}
}
}
拓展:在编写Reverse方法时,char数组转化成String字符串输出时,经常会输出很奇怪的结果,如[C@1b6d3586,此时应该改写成String.valueOf(str),就可以输出正常的字符串的值。