这一期我们把数组剩余的几个问题一并解决,之后我还会出一期数组复盘。
剩余的问题:
1. 数组轮转问题
2. 数组区间问题
3.字符串替换空格问题
LeetCode189. 轮转数组https://leetcode.cn/problems/rotate-array/
一、LeetCode189. 轮转数组
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3 输出:[5,6,7,1,2,3,4]
解释: 向右轮转 1 步:[7,1,2,3,4,5,6]
向右轮转 2 步:[6,7,1,2,3,4,5]
向右轮转 3 步:[5,6,7,1,2,3,4]
示例 2:
输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右轮转 1 步: [99,-1,-100,3] 向右轮转 2 步: [3,99,-1,-100]
一)方法一:暴力解法,数组元素从后往前遍历,将前一个元素赋值给后一个,用两层循环
解决。缺点是时间复杂度太高,测试能过,但是提交时会超出时间限制。
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k = k % n;
for (int i = 0; i < k; i++){
int temp = nums[n - 1];
for (int j = n - 1; j >0; j--){
nums[j] = nums[j - 1];
}
nums[0] = temp;
}
}
}
二)方法二:数组翻转
1. 首先对整个数组实行翻转,例如 [1,2,3,4,5,6,7] 我们先将其整体翻转成[7,6,5,4,3,2,1]。
2. 从 k 处分隔成左右两个部分,这里就是根据k将其分成两组 [7,6,5] 和[4,3,2,1]。
3. 最后将两个再次翻转就得到[5,6,7] 和[1,2,3,4],最终结果就是[5,6,7,1,2,3,4]
上代码~
class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end){
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}
效果如图所示
LeetCode228. 汇总区间https://leetcode.cn/problems/summary-ranges/
二、LeetCode228. 汇总区间
给定一个 无重复元素 的 有序 整数数组 nums
。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums
的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums
的数字 x
。
列表中的每个区间范围 [a,b]
应该按如下格式输出:
"a->b"
,如果a != b
"a"
,如果a == b
示例 1:
输入:nums = [0,1,2,4,5,7] 输出:["0->2","4->5","7"] 解释:区间范围是: [0,2] --> "0->2" [4,5] --> "4->5" [7,7] --> "7"
示例 2:
输入:nums = [0,2,3,4,6,8,9] 输出:["0","2->4","6","8->9"] 解释:区间范围是: [0,0] --> "0" [2,4] --> "2->4" [6,6] --> "6" [8,9] --> "8->9"
思路:这题就用双指针的思想来做,slow指针在初始位置,让fast指针来遍历,当不连续时,将slow指针的下标改成fast+1.
代码如下
public static List<String> summaryRanges(int[] nums) {
List<String> res = new ArrayList<>(); // 创建结果列表
int slow = 0; // 慢指针,指向每个区间的起始位置
for (int fast = 0; fast < nums.length; fast++) { // 快指针,用于遍历数组
if (fast + 1 == nums.length || nums[fast] + 1 != nums[fast + 1]) { // 判断当前数和下一个数是否连续
StringBuilder sb = new StringBuilder(); // 创建字符串构造器,用于拼接区间
sb.append(nums[slow]); // 添加当前区间的起始元素
if (slow != fast) { // 如果慢指针不等于快指针,表示区间有多个元素
sb.append("->").append(nums[fast]); // 添加区间的结束元素
}
res.add(sb.toString()); // 将拼接好的区间添加到结果列表
slow = fast + 1; // 更新慢指针为下一个区间的起始位置
}
}
return res; // 返回结果列表
}
这里由于我的知识储备有限,其实我对这些构造器还不是很懂,等以后来解决吧~
三、剑指offer中的字符串替换空格问题
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
代码如下
public String replaceSpace(StringBuffer str) {
String res = "";
for (int i = 0; i < str.length; i++){
char c = str.chatAt(i);
if (c == " ");
res += "%20";
else
res += c;
}
return res;
}