代码随想录算法训练营第2天| 977.有序数组的平方, 209.长度最小的子数组, 59.螺旋矩阵II
977.有序数组的平方
自己看到题目的第一想法
By squaring a array of non-decreasing order, I am sure that both the two end of the array is the largest two number inside the array. Therefore, I can create an extra array with the same size. Then I can use two pointers to compare the two end of the array, and put the larger one into the new array.
It takes for me more than half an hour to think about the problem because initially I was trying to swap the value of two pointers in-place.
class Solution {
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i] = nums[i] * nums[i];
}
int[] ans = new int[nums.length];
int p = nums.length - 1;
int l = 0, r = nums.length - 1;
while (l <= r) {
if (nums[l] < nums[r]) {
ans[p] = nums[r];
r--;
} else {
ans[p] = nums[l];
l++;
}
p--;
}
return ans;
}
}
看完代码随想录之后的想法
Same with my intial thought. Just a small enhancement. I don't need to calculate the square of each value in array first, I can do it in runtime instead
class Solution {
public int[] sortedSquares(int[] nums) {
int[] ans = new int[nums.length];
int p = nums.length - 1;
int l = 0, r = nums.length - 1;
while (l <= r) {
if (nums[l] * nums[l] < nums[r] * nums[r]) {
ans[p] = nums[r] * nums[r];
r--;
} else {
ans[p] = nums[l] * nums[l];
l++;
}
p--;
}
return ans;
}
}
209.长度最小的子数组
自己看到题目的第一想法
I was unable to finish the question because I misunderstood the question
看完代码随想录之后的想法
Brute Force
Since the time complexity is O(n^2), it exceed time limit
class Solution {
public int minSubArrayLen(int target, int[] arr) {
int minLen = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
int sum = 0;
for (int j = i; j < arr.length; j++) {
// System.out.println("i: " + i + ", j: " + j + ", sum: " + sum);
sum += arr[j];
int len = j - i + 1;
if (sum >= target) {
minLen = Math.min(minLen, len);
}
}
sum -= arr[i];
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
}
Sliding Window
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int minLen = Integer.MAX_VALUE;
int curSum = 0;
int start = 0;
for (int end = 0; end < nums.length; end++) {
curSum += nums[end];
while (curSum >= target) {
minLen = Math.min(minLen, end - start + 1);
curSum -= nums[start];
start++;
}
}
return minLen == Integer.MAX_VALUE ? 0 : minLen;
}
}
Conclusion
Every problems can be solved by simply searching through all the possible solutions in solution space. In order to elimiate the number of search required, many clever algorithm is invented. For example, the binary search reduce the search space by half each time. The sliding window in the above question elimate array that are subarray that have longer length than the already satified subarray. These solution can never be the ans so can be skipped
59.螺旋矩阵II
自己看到题目的第一想法
My first idea is to simulate a person walking the circular order in the square. For example, keep walking to the right until it crash the wall and then change the direction to down. But I cannot finished it.
看完代码随想录之后的想法
This is a pure simulation problem. The most important concept to be applied is similar to the 左闭右开 [left, right) in day 1. Since it is a square, using 左闭右开 can make the logic in four sides more consistent.
One difficult point in this question is to determine how many cycles there are? The answer is the same for both odd and even number, which is n/2, however there need a special handling for the odd number.
The overall logic for this question is to handle four sides seperately. For each cycle, increase one layer from the wall of the four sides.
class Solution {
public int[][] generateMatrix(int n) {
int[][] ans = new int[n][n];
int startCol = 0;
int startRow = 0;
int offset = 1;
int circu = 0;
int count = 1;
while (circu <= n / 2) {
int j;
int i;
for (j = startCol; j < n - offset; j++) {
ans[startRow][j] = count;
count++;
}
for (i = startRow; i < n - offset; i++) {
ans[i][j] = count;
count++;
}
for (; j > startRow; j--) {
ans[i][j] = count;
count++;
}
for (; i > startRow; i--) {
ans[i][j] = count;
count++;
}
circu++;
startCol++;
startRow++;
offset++;
}
if (n % 2 == 1) {
ans[n / 2][n / 2] = count;
}
return ans;
}
}