对于字符串 s
和 t
,只有在 s = t + t + t + ... + t + t
(t
自身连接 1 次或多次)时,我们才认定 “t
能除尽 s
”。
给定两个字符串 str1
和 str2
。返回 最长字符串 x
,要求满足 x
能除尽 str1
且 x
能除尽 str2
。
示例 1:
输入:str1 = "ABCABC", str2 = "ABC" 输出:"ABC"
示例 2:
输入:str1 = "ABABAB", str2 = "ABAB" 输出:"AB"
示例 3:
输入:str1 = "LEET", str2 = "CODE" 输出:""
这是一道简单题,但其实也没那么简单,可以拿这道题熟悉一下字符串的api方法
贴下代码
class Solution {
public String gcdOfStrings(String str1, String str2) {
// 求最大公因子长度
String gcdString = str1 + str2; // 连接两个字符串
if (!gcdString.equals(str1 + str2)) {
return "";
}
int len1 = str1.length();
int len2 = str2.length();
int gcdLength = gcd(len1, len2); // 计算长度的最大公因数
// 取公因子字符串
String divisor = str1.substring(0, gcdLength);
// 检查 publicString 是否能除尽 str1 或 str2
if (str1.equals(divisor.repeat(len1 / gcdLength)) && str2.equals(divisor.repeat(len2 / gcdLength))) {
return divisor;
}
return "";
}
// 辗转相除法求最大公因数
private int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}
给你一个字符串 s
,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 'a'
、'e'
、'i'
、'o'
、'u'
,且可能以大小写两种形式出现不止一次。
示例 1:
输入:s = "IceCreAm"
输出:"AceCreIm"
解释:
s
中的元音是 ['I', 'e', 'e', 'A']
。反转这些元音,s
变为 "AceCreIm"
.
示例 2:
输入:s = "leetcode"
输出:"leotcede"
这也是道简单题,这里提供两种方法,第一种纯练api的,要说新颖就是拿个特殊字符代替元音字符并记录下元音字符之后在逆序插入,这里可以在原字符串上操作不用StringBuilder
import java.util.ArrayList;
import java.util.List;
class Solution {
public String reverseVowels(String s) {
int len = s.length();
List<Character> list = new ArrayList<>(); // 使用 Character 而不是 char
StringBuilder sb = new StringBuilder();
// 将元音和非元音分开处理
for (int i = 0; i < len; i++) {
if (isV(s.charAt(i))) {
sb.append('_'); // 用一个特殊符号替代元音
list.add(s.charAt(i)); // 存储元音
} else {
sb.append(s.charAt(i)); // 直接添加非元音
}
}
// 从 list 中逆序插入元音到 sb 中
for (int i = 0; i < len; i++) {
if (sb.charAt(i) == '_') { // 找到占位符
sb.setCharAt(i, list.remove(list.size() - 1)); // 从结尾取出元音并替换
}
}
return sb.toString();
}
public boolean isV(char ch) { // 改为 boolean 返回类型
return ch == 'a' || ch == 'A' ||
ch == 'e' || ch == 'E' ||
ch == 'i' || ch == 'I' ||
ch == 'o' || ch == 'O' ||
ch == 'u' || ch == 'U';
}
}
第二种就是官方推荐的双指针方法,很适合这种两边操作的题目也很优雅
class Solution {
public String reverseVowels(String s) {
int n = s.length();
char[] arr = s.toCharArray();
int i = 0, j = n - 1;
while (i < j) {
while (i < n && !isVowel(arr[i])) {
++i;
}
while (j > 0 && !isVowel(arr[j])) {
--j;
}
if (i < j) {
swap(arr, i, j);
++i;
--j;
}
}
return new String(arr);
}
public boolean isVowel(char ch) {
return "aeiouAEIOU".indexOf(ch) >= 0;
}
public void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue
" 输出:"blue is sky the
"
示例 2:
输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
这个题目和上面的类似,但这里可以用java提供的api写更简单
class Solution {
public String reverseWords(String s) {
// 去除首尾空格,并使用正则表达式将多个空格替换为单个空格
String trimmedString = s.trim().replaceAll("\\s+", " ");
// 将处理后的字符串按空格分割成单词数组
String[] words = trimmedString.split(" ");
// 使用 StringBuilder 来构建反转后的字符串
StringBuilder reversedString = new StringBuilder();
// 从后往前遍历单词数组
for (int i = words.length - 1; i >= 0; i--) {
reversedString.append(words[i]);
// 如果不是最后一个单词,添加空格
if (i != 0) {
reversedString.append(" ");
}
}
return reversedString.toString();
}
}
或者
class Solution {
public String reverseWords(String s) {
// 除去开头和末尾的空白字符
s = s.trim();
// 正则匹配连续的空白字符作为分隔符分割
List<String> wordList = Arrays.asList(s.split("\\s+"));
Collections.reverse(wordList);
return String.join(" ", wordList);
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/reverse-words-in-a-string/solutions/194450/fan-zhuan-zi-fu-chuan-li-de-dan-ci-by-leetcode-sol/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。