目录
- 1.镜像对之间最小绝对距离
- 2.插入区间
- [3.螺旋矩阵 II](#3.螺旋矩阵 II)
- [4. 旋转链表](#4. 旋转链表)
1.镜像对之间最小绝对距离
给你一个整数数组 nums。
镜像对 是指一对满足下述条件的下标 (i, j):
0 <= i < j < nums.length,并且
reverse(nums[i]) == nums[j],其中 reverse(x) 表示将整数 x 的数字反转后形成的整数。反转后会忽略前导零,例如 reverse(120) = 21。
返回任意镜像对的下标之间的 最小绝对距离。下标 i 和 j 之间的绝对距离为 abs(i - j)。
如果不存在镜像对,返回 -1。
示例 1:
输入: nums = [12,21,45,33,54]
输出: 1
解释:
镜像对为:
(0, 1),因为 reverse(nums[0]) = reverse(12) = 21 = nums[1],绝对距离为 abs(0 - 1) = 1。
(2, 4),因为 reverse(nums[2]) = reverse(45) = 54 = nums[4],绝对距离为 abs(2 - 4) = 2。
所有镜像对中的最小绝对距离是 1。
示例 2:
输入: nums = [120,21]
输出: 1
解释:
只有一个镜像对 (0, 1),因为 reverse(nums[0]) = reverse(120) = 21 = nums[1]。
最小绝对距离是 1。
示例 3:
输入: nums = [21,120]
输出: -1
解释:
数组中不存在镜像对。
思路
哈希保存元素值及下标位置,从后往前遍历,若翻转元素在哈希表中有存储,表明遍历过,求距离
java
class Solution {
public int minMirrorPairDistance(int[] nums) {
int n = nums.length;
Map<Integer,Integer> map = new HashMap<>(n,1);
int minDis = n;
for(int i = n-1;i>=0;i--){
int reNum = reverseNum(nums[i]);
if(map.containsKey(reNum)){
int curDis = map.get(reNum)-i;
minDis = Math.min(curDis,minDis);
}
map.put(nums[i],i);
}
return minDis==n?-1:minDis;
}
private int reverseNum(int num){
int ans = 0;
while(num!=0){
ans = ans*10 + num%10;
num /= 10;
}
return ans;
}
}
时间复杂度: O ( n ) O(n) O(n) ,近似 O ( n ) O(n) O(n),哈希表的遍历时间是近似O(1),这里初始化时由于知道元素个数,因此预设了哈希表大小,防止因动态扩容增加时间
空间复杂度: O ( n ) O(n) O(n)
2.插入区间
给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。
在 intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。
返回插入之后的 intervals。
注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。
示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
示例 2:
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
思路
逆向思维,考虑什么情况下新区间不会与原区间重叠,用一个标志位来标记newInterval是否已经加入列表。由于原区间是按start升序排列的,因此只考虑[starti,endi],
标志位为false情况下:
若newInterval在starti左边,表明区间i与newInterval不重叠,且i-1区间前没有如列表,此时将两个区间放入列表,并置标志位为true,若newInterval在endi右边,表明不重叠,但是否与i+1不重叠,等下一个循环判断,此时区间i放入列表。除此之外,则区间i和newaInterval会重叠,合并区间,再移到下一个区间判断,直至结束,若所有区间判断完,标志位还是false,表明newInterval还没加入列表,则加入列表
标志位为true情况下:
直接把剩余区间放入列表即可
java
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
//判断newInterval是否与某个区间有交集
List<int[]> ans = new ArrayList<>();
boolean isUnion = false;//表明newInterval是否被消化掉
for(int i=0;i<intervals.length;i++){
if(!isUnion&&newInterval[0]>intervals[i][1]){//没有被消化掉
ans.add(intervals[i]);
continue;
}else if(!isUnion&&newInterval[1]<intervals[i][0]){
ans.add(newInterval);
ans.add(intervals[i]);
isUnion = true;//被消化掉了
continue;
}else if(!isUnion&&newInterval[0]>=intervals[i][0]&&newInterval[1]<=intervals[i][1]){
ans.add(intervals[i]);
isUnion = true;
continue;
}else if(!isUnion){//否则未被消化掉时
newInterval[0] = Math.min(intervals[i][0],newInterval[0]);
newInterval[1] = Math.max(intervals[i][1],newInterval[1]);
continue;
}
ans.add(intervals[i]);
}
if(!isUnion){
ans.add(newInterval);
}
return ans.toArray(new int[0][]);
}
}
时间复杂度: O ( N ) O(N) O(N) N表示区间数量
空间复杂度: O(1)
3.螺旋矩阵 II
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
实例1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
思路
拟合螺旋操作,按层拟合,分为四个方向,上,右,下,左,拟合到最里层结束
java
class Solution {
public int[][] generateMatrix(int n) {
//一圈一圈的数数
int l = 0, r = n-1;
int[][] ans = new int[n][n];
int val = 1;
while(l<r){
//上
for(int i=l;i<r;i++){
ans[l][i] = val++;
}
//右
for(int i=l;i<r;i++){
ans[i][r] = val++;
}
//下
for(int i=r;i>l;i--){
ans[r][i] = val++;
}
//左
for(int i=r;i>l;i--){
ans[i][l] = val++;
}
l++;
r--;
}
if(l==r){
ans[l][r] = n*n;
}
return ans;
}
}
时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
4. 旋转链表
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
示例 2:
输入:head = [0,1,2], k = 4
输出:[2,0,1]
思路
两个指针,两个指针间的长度为k(k取链表长度的余数),则前一个指针下一个元素即为新的头节点,后一个指针指向旧的头节点
java
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head==null||k==0){
return head;
}
int size = 0;
ListNode node = head;
while(node!=null){
size++;
node = node.next;
}
k = k%size;
ListNode l = head;
ListNode r = head;
while(k-->0){
r = r.next;
}
while(r.next!=null){
l = l.next;
r = r.next;
}
r.next = head;
head = l.next;
l.next=null;
return head;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)