【2022.12.17】备战春招Day12——每日一题 + 76. 最小覆盖子串 + 24. 两两交换链表中的节点

【每日一题】1764. 通过连接另一个数组的子数组得到一个数组
题目描述

给你一个长度为 n 的二维整数数组 groups ,同时给你一个整数数组 nums

你是否可以从 nums 中选出 n 个 不相交 的子数组,使得第 i 个子数组与 groups[i] (下标从 0 开始)完全相同且如果 i > 0 ,那么第 (i-1) 个子数组在 nums 中出现的位置在第 i 个子数组前面。(也就是说,这些子数组在 nums 中出现的顺序需要与 groups 顺序相同)

如果你可以找出这样的 n 个子数组,请你返回 true ,否则返回 false 。

输入:groups = [[1,-1,-1],[3,-2,0]], nums = [1,-1,0,1,-1,-1,3,-2,0]
输出:true
解释:你可以分别在 nums 中选出第 0 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 和第 1 个子数组 [1,-1,0,1,-1,-1,3,-2,0] 。
这两个子数组是不相交的,因为它们没有任何共同的元素。

题目解析

在这里插入图片描述

class Solution {
    public boolean canChoose(int[][] groups, int[] nums) {
        int i = 0;
        // k指向nums,i指向groups的数组
        for(int k = 0; k < nums.length && i < groups.length;){
            //判断当前k指向的和i指向的是否相等
            if(nums[k] == groups[i][0]){
                if(check(nums, groups[i], k)){
                    // 判断group下一个数组
                    k += groups[i].length;
                    i++;
                }else{
                    k++;
                }
            }else{
                k++;
            }
        }
        //如果groups数组判断完,则代表都可以找到
        if(i == groups.length) return true;
        return false;
    }

    public boolean check(int[] nums, int[] g, int k){
        if(k + g.length > nums.length) return false;
        for(int i = 0; i < g.length; i++){
            if(nums[k + i] != g[i]) return false;
        }
        return true;
    }
}
【leetcode hot 100】76. 最小覆盖子串
题目描述

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。

题目解析

滑动窗口】:该题需要找到子字符串,经典的滑动窗口题目,使用双指针left,right;
right不断向右扩张,直至left和right中包含的是可行解。
left不断向右收缩,直至left和right中包含的不是可行解。
哈希表】:将t中的字符及其个数使用哈希表来保存。
【count】:用来判断目前子字符串是否是可行解

class Solution {
    public String minWindow(String s, String t) {
        if(s.length() < t.length()) return "";
        //哈希表,记录t中包含的字符,如果为正,代表目前子字符串不是可行解,如果某一个字符为负,则说明字符串有冗余
        int[] record = new int[128];
        for(char c : t.toCharArray()){
            record[c]++;
        }
        // count用来记录 目前的子字符串是不是可行解
        int count = t.length();
        int min = Integer.MAX_VALUE;
        int left = 0, right = 0;
        int min_left = 0;
        for(; right < s.length(); right++){
            //判断目前的字符是不是我们需要的
            if(record[s.charAt(right)] > 0){
                count--;
            }
            record[s.charAt(right)]--;
            //如果目前子字符串已经满足要求,则收缩left
            while(left <= right && count == 0){
                if(min > (right - left + 1)){
                    min_left = left;
                    min = right - left + 1;
                }
                record[s.charAt(left)]++;
                if(record[s.charAt(left)] > 0){    
                    count++;
                }
                left++;
            }
        }
        if(min == Integer.MAX_VALUE) return "";
        return s.substring(min_left, min_left + min);
    }
}
【代码随想录】24. 两两交换链表中的节点
题目描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。

在这里插入图片描述

题目解析
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummyHead = new ListNode(0, head);
        // 单数与偶数交换
        ListNode pre = dummyHead; //上一个节点
        ListNode cur = head; //目前的节点
        int index = 0;
        while(cur != null){
            // 每次改变两个 cur为第一个 cur.next为第二个
            if(cur.next == null){
                pre.next = cur;
                break;
            }
            ListNode temp = cur.next.next;
            pre.next = cur.next;
            cur.next.next = cur;
            cur.next = temp;
            pre = cur;
            cur = temp;
        }
        return dummyHead.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值