学习目标:
- 977.有序数组的平方
- 209.长度最小的子数组
- 59.螺旋矩阵II
- 分布式常见面试题(上)
学习内容:
977.有序数组的平方
题目链接 &&文章讲解
给你一个按非递减顺序排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序排序。
双指针法
class Solution {
public int[] sortedSquares(int[] nums) {
int right=nums.length-1,left=0;
int[] res = new int[nums.length];
int i=nums.length-1;
while(left<=right){//left和right相等时所指向的元素也要更新
int leftSquare=nums[left]*nums[left];
int rightSquare=nums[right]*nums[right];
if(leftSquare>=rightSquare){
res[i--]=leftSquare;
left++;
}else{
res[i--]=rightSquare;
right--;
}
}
return res;
}
}
- 需要考虑数组中存在负数的情况,数组平方的最大值就数组的两端,即是最左边或最右边,使用双指针寻找最大值从尾部更新数组
- 循环终止条件为left <= right,因为最后要处理两个元素,left和right相等时所指向的元素也要更新,否则会丢失一个元素
- 双指针时间复杂度O(n),暴力排序时间复杂度O(n + nlog n)
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
滑动窗口
- 窗口内:满足其和 ≥ s 的长度最小的连续子数组
- 起始位置移动:如果当前窗口的值大于s了,窗口就要向前移动了
- 结束位置移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i=0,sum=0,len=0;
int res = Integer.MAX_VALUE;
for(int j=0;j<nums.length;j++){
sum=sum+nums[j];
while(sum>=target){//使用while而不是if 起始位置可能后移更新多次
len=j-i+1;
res=res>=len?len:res;
sum=sum-nums[i++];
}
}
return res==Integer.MAX_VALUE?0:res;
}
}
- 滑动窗口本质是满足了单调性,即左右指针只会往一个方向走且不会回头。收缩的本质即去掉不再需要的元素,更新起始位置时用while而不是if,不断比较子序列是否符合条件 [1,1,1,1,99]
- 数组有负数则无法使用滑动窗口,无论收缩或者扩张窗口,值的总和都可能增加或减少,就不像之前收缩一定变小,扩张一定变大。
- 时间复杂度:每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是为2 × n即O(n)
59.螺旋矩阵II
给你一个正整数 n ,生成一个包含 1 到 n² 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
顺时针 左闭右开:
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int start=0;
int count=0;
int val=1;
while(count++<n/2){//控制循环次数
int i=start;
int j=start;
//n=4
//第一圈:[0,3) [3,0)
//第二圈:[1,2) [2,1)
//n=5
//第一圈:[0,4) [4,0)
//第二圈:[1,3) [3,1)
//第三圈:res[2][2]
// 模拟填充上行从左到右[start, n-start-1)
for(;j<n-start-1;j++){//satrt -> n-start-2
res[i][j]=val++;
}
// 模拟填充右列从上到下[start, n-start-1)
for(;i<n-start-1;i++){
res[i][j]=val++;
}
// 模拟填充下行从右到左[n-start-1,start)
for(;j>start;j--){//n-start-1 -> start-1
res[i][j]=val++;
}
// 模拟填充左列从下到上[n-start-1,start)
for(;i>start;i--){
res[i][j]=val++;
}
start++;
}
if (n % 2 == 1) {
res[n/2][n/2] = val;
}
return res;
}
}
分布式
相关理论
- CAP理论(Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性))
- BASE ( Basically Available(基本可用)、Soft-state(软状态) 和 Eventually Consistent(最终一致性))
- Paxos 算法(Basic Paxos 算法、Multi-Paxos 思想)
- Raft集群分布式共识算法
- Gossip 协议 随即传播特性
API网关
- 网关概念及功能(请求转发+请求过滤)
- 常见的网关系统
- Spring Cloud Gateway工作流程
- Spring Cloud Gateway路由和断言
- Spring Cloud Gateway过滤器
- Spring Cloud Gateway自定义全局异常处理
分布式ID
- 分布式ID概念及要求
- 常见解决方案(数据库,算法(UUID 雪花算法,开源框架)
分布式锁
- 分布式锁概念及具备条件(共享资源的互斥访问)
- 常见实现方案(关系型数据库如mysql,分布式协调服务 ZooKeeper,分布式键值存储系统如 Redis 、Etcd )