文章目录
- 2024.5.26(5题)
- 1446.连续字符
- 题解一
- 题解二
- 2824.统计和小于目标的下标对数目
- 题解一
- 题解二
- 1768.交替合并字符串
- 题解一
- 题解二
- 题解三
- 796.旋转字符串
- 题解一
- 题解二
- 1304.和为零的 N 个不同整数
- 题解一
- 题解二
2024.5.26(5题)
1446.连续字符
双指针
题目链接
给你一个字符串 s
,字符串的**「能量」**定义为:只包含一种字符的最长非空子字符串的长度。
请你返回字符串 s
的 能量。
示例 1:
输入:s = "leetcode"
输出:2
解释:子字符串 "ee" 长度为 2 ,只包含字符 'e' 。
示例 2:
输入:s = "abbcccddddeeeeedcba"
输出:5
解释:子字符串 "eeeee" 长度为 5 ,只包含字符 'e' 。
提示:
1 <= s.length <= 500
s
只包含小写英文字母。
题解一
class Solution {public int maxPower(String s) {int maxPower = 1;int currentPower = 1;for (int i = 1; i < s.length(); i++) {if (s.charAt(i) == s.charAt(i - 1)) {currentPower++;maxPower = Math.max(maxPower, currentPower);} else {currentPower = 1;}}return maxPower;}
}
- 这种方法通过一次遍历字符串来计算最长的只包含一种字符的子字符串长度。
- 初始化
maxPower
和currentPower
为 1。 - 遍历字符串,每次检查当前字符和前一个字符是否相同。
- 如果相同,增加
currentPower
,并更新maxPower
。 - 如果不同,将
currentPower
重置为 1。
- 如果相同,增加
- 返回
maxPower
- 初始化
题解二
class Solution {public int maxPower(String s) {int maxPower = 1;int start = 0;for (int end = 1; end < s.length(); end++) {if (s.charAt(end) != s.charAt(start)) {start = end;}maxPower = Math.max(maxPower, end - start + 1);}return maxPower;}
}
- 这种方法使用双指针,一个指针遍历字符串,另一个指针记录当前子字符串的起始位置。
- 初始化
maxPower
为 1,start
为 0。 - 遍历字符串,用
end
指针指向当前字符。 - 如果当前字符与
start
指向的字符不同,移动start
到end
。 - 更新
maxPower
为end - start + 1
的最大值。 - 返回
maxPower
。
- 初始化
2824.统计和小于目标的下标对数目
双指针
题目链接
给你一个下标从 0 开始长度为 n
的整数数组 nums
和一个整数 target
,请你返回满足 0 <= i < j < n
且 nums[i] + nums[j] < target
的下标对 (i, j)
的数目。
示例 1:
输入:nums = [-1,1,2,3,1], target = 2
输出:3
解释:总共有 3 个下标对满足题目描述:
- (0, 1) ,0 < 1 且 nums[0] + nums[1] = 0 < target
- (0, 2) ,0 < 2 且 nums[0] + nums[2] = 1 < target
- (0, 4) ,0 < 4 且 nums[0] + nums[4] = 0 < target
注意 (0, 3) 不计入答案因为 nums[0] + nums[3] 不是严格小于 target 。
示例 2:
输入:nums = [-6,2,5,-2,-7,-1,3], target = -2
输出:10
解释:总共有 10 个下标对满足题目描述:
- (0, 1) ,0 < 1 且 nums[0] + nums[1] = -4 < target
- (0, 3) ,0 < 3 且 nums[0] + nums[3] = -8 < target
- (0, 4) ,0 < 4 且 nums[0] + nums[4] = -13 < target
- (0, 5) ,0 < 5 且 nums[0] + nums[5] = -7 < target
- (0, 6) ,0 < 6 且 nums[0] + nums[6] = -3 < target
- (1, 4) ,1 < 4 且 nums[1] + nums[4] = -5 < target
- (3, 4) ,3 < 4 且 nums[3] + nums[4] = -9 < target
- (3, 5) ,3 < 5 且 nums[3] + nums[5] = -3 < target
- (4, 5) ,4 < 5 且 nums[4] + nums[5] = -8 < target
- (4, 6) ,4 < 6 且 nums[4] + nums[6] = -4 < target
提示:
1 <= nums.length == n <= 50
-50 <= nums[i], target <= 50
题解一
class Solution {public int countPairs(List<Integer> nums, int target) {int count = 0;int n = nums.size();for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {if (nums.get(i) + nums.get(j) < target) {count++;}}}return count;}
}
-
暴力双循环
跟标准数组不一样的操作是,这里获取数组长度是
nums.size()
,得到下标的元素是用get(),而不是[]
题解二
class Solution {public int countPairs(List<Integer> nums, int target) {Collections.sort(nums);int count = 0;int n = nums.size();int left = 0;int right = n - 1;while (left < right) {if (nums.get(left) + nums.get(right) < target) {count += (right - left);left++;} else {right--;}}return count;}
}
- 先对数组进行排序,然后使用双指针来找到满足条件的下标对。
- 对数组进行排序。
- 初始化
count
为 0,left
为 0,right
为数组长度减 1。 - 使用双指针遍历数组。
- 如果
nums.get(left) + nums.get(right)
,则将right - left
加到count
,并移动left
指针。 - 否则,移动
right
指针。 - 返回
count
。
1768.交替合并字符串
经典题
题目链接
给你两个字符串 word1
和 word2
。请你从 word1
开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。
返回 合并后的字符串 。
示例 1:
输入:word1 = "abc", word2 = "pqr"
输出:"apbqcr"
解释:字符串合并情况如下所示:
word1: a b c
word2: p q r
合并后: a p b q c r
示例 2:
输入:word1 = "ab", word2 = "pqrs"
输出:"apbqrs"
解释:注意,word2 比 word1 长,"rs" 需要追加到合并后字符串的末尾。
word1: a b
word2: p q r s
合并后: a p b q r s
示例 3:
输入:word1 = "abcd", word2 = "pq"
输出:"apbqcd"
解释:注意,word1 比 word2 长,"cd" 需要追加到合并后字符串的末尾。
word1: a b c d
word2: p q
合并后: a p b q c d
提示:
1 <= word1.length, word2.length <= 100
word1
和word2
由小写英文字母组成
题解一
public class Solution {public String mergeAlternately(String word1, String word2) {StringBuilder merged = new StringBuilder();int i = 0, j = 0;while (i < word1.length() && j < word2.length()) {merged.append(word1.charAt(i++));merged.append(word2.charAt(j++));}while (i < word1.length()) {merged.append(word1.charAt(i++));}while (j < word2.length()) {merged.append(word2.charAt(j++));}return merged.toString();}
}
- 使用双指针分别指向两个字符串的当前位置,交替添加字符。
- 初始化一个
StringBuilder
来构建结果字符串。 - 使用两个指针
i
和j
,分别指向word1
和word2
的当前位置。 - 交替添加字符,直到其中一个字符串被遍历完。
- 添加剩余的字符(如果有)到结果字符串。
- 返回结果字符串。
- 初始化一个
题解二
class Solution {public String mergeAlternately(String word1, String word2) {StringBuilder merged = new StringBuilder();int maxLength = Math.max(word1.length(), word2.length());for (int i = 0; i < maxLength; i++) {if (i < word1.length()) {merged.append(word1.charAt(i));}if (i < word2.length()) {merged.append(word2.charAt(i));}}return merged.toString();}
}
- 这种方法通过循环遍历两个字符串,并使用条件判断来决定添加哪个字符串的字符。
- 初始化一个
StringBuilder
来构建结果字符串。 - 计算两个字符串的最大长度
maxLength
。 - 遍历从 0 到
maxLength
,在每次迭代中根据当前索引是否小于各字符串的长度来决定添加哪个字符。 - 当 i 同时小于两个字符串的长度时,两个if都会执行,是交替拼接
- 返回结果字符串。
- 初始化一个
题解三
class Solution {public String mergeAlternately(String word1, String word2) {int w1 = word1.length();int w2 = word2.length();int index = 0;char[] ans = new char[w1 + w2];for (int i = 0; i < w1 || i < w2; i++) {if (i < w1) {ans[index++] = word1.charAt(i);}if (i < w2) {ans[index++] = word2.charAt(i);}}return new String(ans);}
}
- 使用字符数组来存储结果字符,然后构造结果字符串。
- 与题解二不同的是,这里需要维护一个索引让字符数组往后赋值
796.旋转字符串
题目链接
给定两个字符串, s
和 goal
。如果在若干次旋转操作之后,s
能变成 goal
,那么返回 true
。
s
的 旋转操作 就是将 s
最左边的字符移动到最右边。
- 例如, 若
s = 'abcde'
,在旋转一次之后结果就是'bcdea'
。
示例 1:
输入: s = "abcde", goal = "cdeab"
输出: true
示例 2:
输入: s = "abcde", goal = "abced"
输出: false
提示:
1 <= s.length, goal.length <= 100
s
和goal
由小写英文字母组成
题解一
class Solution {public boolean rotateString(String s, String goal) {if (s.length() != goal.length()) {return false;}String concatenated = s + s;return concatenated.contains(goal);}
}
- 这种方法通过将字符串
s
拼接两次,然后检查goal
是否是拼接后字符串的子串。- 检查
s
和goal
的长度是否相等。如果不相等,直接返回false
。 - 将
s
拼接两次得到concatenated
字符串。 - 检查
goal
是否是concatenated
的子串。 - 返回结果。
- 检查
题解二
class Solution {public boolean rotateString(String s, String goal) {if (s.length() != goal.length()) {return false;}int len = s.length();for (int i = 0; i < len; i++) {String rotated = s.substring(i) + s.substring(0, i);if (rotated.equals(goal)) {return true;}}return false;}
}
-
模拟每次旋转后的字符串是否等于
goal
。-
检查
s
和goal
的长度是否相等。如果不相等,直接返回false
。 -
遍历
s
的每一个字符,将s
进行旋转得到rotated
字符串。substring() 方法返回字符串的子字符串。
public String substring(int beginIndex) 或 public String substring(int beginIndex, int endIndex)
- beginIndex – 起始索引(包括), 索引从 0 开始。
- endIndex – 结束索引(不包括)。
-
如果
rotated
等于goal
,返回true
。 -
遍历结束后,返回
false
。
-
1304.和为零的 N 个不同整数
题目链接
给你一个整数 n
,请你返回 任意 一个由 n
个 各不相同 的整数组成的数组,并且这 n
个数相加和为 0
。
示例 1:
输入:n = 5
输出:[-7,-1,1,3,4]
解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。
示例 2:
输入:n = 3
输出:[-1,0,1]
示例 3:
输入:n = 1
输出:[0]
提示:
1 <= n <= 1000
题解一
class Solution {public int[] sumZero(int n) {int[] result = new int[n];int index = 0;for (int i = 1; i <= n / 2; i++) {result[index++] = i;result[index++] = -i;}if (n % 2 != 0) {result[index] = 0;}return result;}
}
- 对于一个正整数
k
,可以将其对应的负整数-k
也加入数组中,这样k + (-k) = 0
。如果n
是奇数,可以再加入一个 0。- 初始化一个长度为
n
的数组result
。 - 使用一个循环从 1 遍历到
n / 2
,将正负对称数加入数组。 - 如果
n
是奇数,最后加入一个 0。 - 返回结果数组。
- 初始化一个长度为
题解二
class Solution {public int[] sumZero(int n) {int[] result = new int[n];int sum = 0;for (int i = 0; i < n - 1; i++) {result[i] = i + 1;sum += i + 1;}result[n - 1] = -sum;return result;}
}
- 从 1 到
n-1
生成递增的整数,再计算最后一个数使总和为 0。- 初始化一个长度为
n
的数组result
和一个sum
变量。 - 使用一个循环生成从 1 到
n-1
的整数并计算总和。 - 将最后一个元素设为负的总和。
- 返回结果数组。
- 初始化一个长度为