文章目录
前言
4.14 LeetCode633-平方数之和 + LeetCode345-反转字符串中的元音字母
一、平方数之和
题目描述:
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
示例 1:
输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5
示例 2:
输入:c = 3
输出:false
提示:
- 0 <= c <= 2^31 - 1
思路:双指针
- 右指针的初始化:为了降低时间复杂度,将 j 取为 sqrt(target)
- 最多只需要遍历一次 0~sqrt(target),时间复杂度为 O(sqrt(target))
- 只使用了两个额外的变量,空间复杂度为 O(1)
- 注意两个非负整数平方和的取值范围,sum 最好用 long 类型
public boolean judgeSquareSum(int c) {
long i = 0, j = (int) sqrt(c);
while (i <= j) {
long sum = i * i + j * j;
if (sum == c) {
return true;
} else if (sum < c) {
i++;
} else {
j--;
}
}
return false;
}
二、反转字符串中的元音字母
题目描述:
给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 'a'、'e'、'i'、'o'、'u',且可能以大小写两种形式出现不止一次。
示例 1:
输入:s = "hello"
输出:"holle"
示例 2:
输入:s = "leetcode"
输出:"leotcede"
提示:
- 1 <= s.length <= 3 * 105
- s 由 可打印的 ASCII 字符组成
思路:双指针
- 当两个指针都遍历到元音字符时,交换这两个元音字符
- 使用 StringBuilder 类中 replace 函数替换字符串中指定位置的字符
- 使用函数 vowelLetters 快速判断当前字符是否为元音字符
- 时间复杂度 O(N):只需要遍历所有元素一次
- 空间复杂度 O(1):只需要使用两个额外变量
public String reverseVowels(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (!vowelLetters(s.charAt(i))) {
i++;
} else if (!vowelLetters(s.charAt(j))) {
j--;
} else {
StringBuilder sb = new StringBuilder(s);
sb.replace(i, i + 1, s.charAt(j) + "");
sb.replace(j, j + 1, s.charAt(i) + "");
s = sb.toString();
i++;
j--;
}
}
return s;
}
public boolean vowelLetters(char c) {
if (c == 'a' | c == 'e' | c == 'i' | c == 'o' | c == 'u' | c == 'A' | c == 'E' | c == 'I' | c == 'O' | c == 'U') {
return true;
} else {
return false;
}
}
改进:
- 可以将全部元音字符添加到集合 HashSet 中,再用 vowel.contains 方法
private final static HashSet<Character> vowels = new HashSet<>(
Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U')
);
- 可以使用 indexOf 方法
public boolean isVowel(char c) {
return "aeiouAEIOU".indexOf(c) >=0;
}