LeetCode刷题 day13

目录

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)

相关推荐
小马_xiaoen2 小时前
前端虚拟列表(Virtual List)从原理到实战:海量数据渲染终极方案
前端·数据结构·list
炽烈小老头2 小时前
【每天学习一点算法 2026/04/17】多数元素
数据结构·学习·算法
云泽8082 小时前
第十五届蓝桥杯大赛软件赛省赛C/C++大学B组
c语言·c++·算法·蓝桥杯
大模型最新论文速读3 小时前
VQKV:KV Cache 压缩 82% 性能几乎不降
人工智能·深度学习·算法·机器学习·自然语言处理
yongui478343 小时前
基于MSP430和Zigbee技术的煤矿综合监控系统设计与实现
算法
Ww.xh3 小时前
ESP8266连接AI大模型完整指南
人工智能·算法·语言模型
程序员雷欧3 小时前
Redis基础知识全解析:从数据结构到生产实战
数据结构·数据库·redis
俺不要写代码3 小时前
lambda表达式理解
c++·算法
自我意识的多元宇宙3 小时前
二叉树遍历方式代码解读(3层序遍历)
数据结构