13. <tag-数组和双指针(左右指针)>-lt.977-有序数组的平方 + lt.75-颜色分类 2.2
lt.977-有序数组的平方
[案例需求]
[思路分析]
- 简单题简单做, 遍历给定的有序数组的每个数, 把遍历到的每个数进行平方, 放入到新数组,
- 而由于题目要求我们输出的数组是有序的, 如果数组中含有负数, 那么还要对得到的结果数组进行排序后, 再返回.
[代码实现]
class Solution {
public int[] sortedSquares(int[] nums) {
//新数组. 存放平方数
int[] res = new int [nums.length];
int resIndex = 0;
for(int i = 0; i < nums.length; i++){
res[resIndex++] = nums[i] * nums[i];
}
//对数组排序
Arrays.sort(res);
return res;
}
}
[优化1. 数组原地存储平方数, 减少创建新数组的内存]
class Solution {
public int[] sortedSquares(int[] nums) {
//新数组. 存放平方数
//int[] res = new int [nums.length];
//int resIndex = 0;
for(int i = 0; i < nums.length; i++){
nums[i] = nums[i] * nums[i];
}
//对数组排序
Arrays.sort(nums);
return nums;
}
}
- 效率稍微提高了一点点;
[优化2. 左右双指针遍历数组, 每次比较前后双指针的平方数, 大的放入到数组后面]
-
[思路分析]
- 题目给我们的原数组是非递减的, 如果数组中的数都是整数, 那无疑得到的平方数都是递增的,
- 我们要考虑的是数组中含有负数时, 而且负数的绝对值如果比数组中靠后的数大的话, 那无疑平方数会出现前面的数大, 后面的数小;
- 所以这里我们采用双指针, 左指针指向数组的开始, 右指针指向末尾,
- 通过比较左右指针平方数的大小, 把较大的放到数组的末尾(注意,这里是把数组从后向前的索引赋值的)
- 一定要明确的一点是, 原数组是非递减的(
这就意味着平方数最大的要么在数组的最左边(负数), 要么在数组的最右边
), 我们才能使用左右双指针;
-
[代码实现]
class Solution {
public int[] sortedSquares(int[] nums) {
int L = 0;
int R = nums.length - 1;
int[] res = new int[nums.length];
int lastIndex = nums.length - 1;
while(L <= R){
int left = nums[L] * nums[L];
int right = nums[R] * nums[R];
if(left < right){
res[lastIndex--] = right;
R--;
}else{
res[lastIndex--] = left;
L++;
}
}
return res;
}
}
lt.75-颜色分类
[案例需求]
[思路分析]
- 题目大意: 将数组中的数按照 0->1->2的顺序排列, 其中0,1,2都是可重复的;
- 先说一句, 用Arrays.sort(nums)的, 等着感谢信吧(滑稽)
- 前面提过一嘴, 对于有序数组的, 加上或不加上原地修改数组的, 一定要考虑下是否能用双指针解题;
- 这道题, 我们应该想到用左右双指针, 但是左右双指针在这里是用来标注0和2的边界的, 我们还应用一个指针遍历做左右指针之间的数(从L->R), 所以, 这道题用三指针来解比较容易理解;
- 定义指针 i, 遍历数组, 左指针 L, 标记0的右边界, 右指针R, 标记2的左边界
- i 遍历数组, 从L–>R,
- 遇到0的话, 与左指针L交换;
- 遇到1的话, 不说话, 直接 i++;
- 遇到2的话, 与右指针R交换;
这里一定要多体会下, 指针在不同初值上的差别;
[代码实现]
class Solution {
public void sortColors(int[] nums) {
// 0,1,2
//左边0, 中间1, 右边2
//左右指针
int L = 0;
int R = nums.length;
int i = 0;
while(i < R){
if(nums[i] == 0){
swap(i, L, nums);
L++;
i++;
}else if(nums[i] == 1){
i++;
}else if(nums[i] == 2){
R--;
swap(i, R, nums);
}
}
}
public void swap(int l, int r, int[] nums){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)