JAVA数组题目及数组总结
目录
1. 数组练习题
1.1 LeetCode977.有序数组的平方
题目描述:给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
暴力解法:将nums依次平方后,利用sort函数排序。
class Solution {
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; i++){
nums[i] = nums[i]*nums[i];
}
Arrays.sort(nums);
return nums;
}
}
双指针解法:数组nums是非递减排序,平方后的最大值是最左边或者最右边。可以定义左指针left和右指针right。比较两边的大小,将较大值保存到res数组中,再更新指针。
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int[] res = new int[nums.length];
int i = nums.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]){
res[i--] = nums[left]*nums[left];
left++;
}else {
res[i--] = nums[right]*nums[right];
right--;
}
}
return res;
}
}
1.2 LeetCode59.螺旋矩阵II
题目描述:给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
思路:循环不变量,每次处理的区间的原则都是左闭右开。
class Solution {
public int[][] generateMatrix(int n) {
int res[][] = new int[n][n];
int i;
int j;
//每一圈的起始,每圈循环后需要更新
int startX = 0;
int startY = 0;
int count = 1;
//偏移值,每圈循环后需要更新
int offset = 1;
//循环次数,边长为n,循环(n/2)圈
int loop = 0;
while ( loop ++ < (n/2)) {
//上边
for(j = startY;j < n - offset; j++) {
res[startX][j] = count++;
}
//右边
for(i = startX;i < n - offset; i++) {
res[i][j] = count++;
}
//下边
for(;j > startY;j--) {
res[i][j] = count++;
}
//左边
for(;i > startX;i--) {
res[i][startY] = count++;
}
offset++;
startY++;
startX++;
}
if(n % 2 == 1) {
res[n/2][n/2] = count;
}
return res;
}
}
1.3 LeetCode209. 长度最小的子数组
暴力解法:两重循环
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int n;//满足条件的元素个数
int sum;
for(int slow = 0; slow < nums.length; slow ++) {
sum = 0;
for(int fast = slow; fast < nums.length; fast++) {
sum += nums[fast];
if(sum >= target) {
n = fast - slow + 1;
res = res < n? res : n;
break;
}
}
}
return res == Integer.MAX_VALUE?0 : res;
}
}
滑动窗口法:
时间复杂度为O(n),每个元素被放入一次取出一次,一共操作2n次。
什么是滑动窗口?不断调节窗口起始和结束位置,得到结果。滑动窗口用一个for循环来表示结束位置,根据窗口的情况,不断调节起始位置。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int n;
int sum = 0;
int left = 0;
for(int right = 0; right < nums.length; right ++) {
sum += nums[right];
while (sum >= target){
n = right - left + 1;
res = res < n? res : n;
sum -= nums[left++];//不断调节起始位置
}
}
return res == Integer.MAX_VALUE?0 : res;
}
}