977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
思路:
- 暴力解法:直接遍历乘法后排序
- 双指针:从示例中会发现两边平方后大中间最小,选择双指针从两边向中间遍历,反向生成新的数组。
/** * 双指针 * 定义一个新数组和A数组一样的大小,让k指向result数组终止位置。 * * 如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。 * * 如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i]; 。 */ public class Solusion { public static int[] sortedSquares(int[] nums) { int left = 0; int right = nums.length -1; int[] result = new int[nums.length]; int index = result.length -1; while (left <=right){ //此处小于等于是因为若等于就停止循环,会有一个数没有取到 if (nums[left] * nums[left] > nums[right] * nums[right]){ result[index--] = nums[left] * nums[left]; ++left; //前进一位 }else { //此处包含了=是因为等于的时候娶那边都可以 result[index--] = nums[right] * nums[right]; --right;//减少一位 } } return result; } }
解题:
//暴力解法
public class Solusion {
public int[] sortedSquares(int[] nums) {
int[] new_nums = new int [nums.length];
for (int i = 0; i < nums.length; i++) {
new_nums[i] = nums[i] * nums[i];
}
Arrays.sort(new_nums);
return new_nums;
}
}
//快排:每次将基准点归位,分而治之,二分思想,然后进行递归
public class QuickSort implements IArraySort {
@Override
public int[] sort(int[] sourceArray) throws Exception {
// 对 arr 进行拷贝,不改变参数内容
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
return quickSort(arr, 0, arr.length - 1);
}
private int[] quickSort(int[] arr, int left, int right) {
if (left < right) {
int partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex - 1);
quickSort(arr, partitionIndex + 1, right);
}
return arr;
}
//每次找到基准值,进行分区。
private int partition(int[] arr, int left, int right) {
// 设定基准值(pivot)
int pivot = left;
int index = pivot + 1;
for (int i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index - 1;
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组[4,3]
是该条件下的长度最小的子数组
思路:
- 暴力解法:双层for循环,找到最小的长度
- 移动窗口:所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果.
想要使用一个for循环代替两个for循环做的事情,就应该想到遍历的数字代表的应该是窗口的起始位置,还是终止位置,若是起始位置,那么终止的位置难免也需要遍历,又变成了暴力解法,所以只能是表示终止位置。那么滑动窗口的起始位置如何移动呢? 首先需要考虑三个问题:
- 窗口是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
解题:
/**
* 暴力解法:双层for循环,找到最小长度
*/
public class Solusion {
public static int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
if (n == 0){
return 0;
}
int ans = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
int sum = 0; //每次从新的位置遍历,查找最小长度数组。
for (int j = i; j < n; j++) {
sum += nums[j];
if (sum >=target){
ans = Math.min(ans,j-i+1);
break; //因为我们是想找到最小的数组长度
}
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
class Solution {
// 滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int start = 0;
int sum =0;
int result = Integer.MAX_VALUE;//用最大值先去比较确定最小值
int subLength =0;
int size = nums.length;
for (int i = 0; i < size; i++) {
sum +=nums[i];
while (sum >= target){//窗口定义及窗口移动条件
subLength = i - start +1; //窗口大小
result = result < subLength ? result:subLength;//每次取到最小值
sum-=nums[start++];//移动后减去起始位置移动对应值
}
}
return result == Integer.MAX_VALUE? 0 : result; //没有进去while循环的情况
}
59.螺旋矩阵II
思路:坚持循环不变量原则
每转一圈,可以左闭右开,这样才不会重复,不会乱。
解题:
class Sulotion{
public int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数,也间接控制每次循环的该减少的偏移量
int[][] res = new int[n][n];
int start = 0; // 每次循环的开始点(start, start)
int count = 1; // 定义填充数字
int i, j;
while (loop++ < n / 2) { // 判断边界后,loop从第一圈开始
// 模拟上侧从左到右,i不变,j增加到n-loop
for (j = start; j < n - loop; j++) {
res[start][j] = count++;
}
// 模拟右侧从上到下,j不变,i从0增加到n-loop
for (i = start; i < n - loop; i++) {
res[i][j] = count++;
}
// 模拟下侧从右到左,i不边,j减小到
for (; j >= loop; j--) {
res[i][j] = count++;
}
// 模拟左侧从下到上,j不变,i减小到
for (; i >= loop; i--) {
res[i][j] = count++;
}
start++;
}
if (n % 2 == 1) {
res[start][start] = count;
}
return res;
}
}