LeetCode: 第 161 场周赛题解

本文解析了LeetCode第161场周赛的四道题目,包括交换字符使得字符串相同、统计优美子数组、移除无效的括号及检查好数组。详细介绍了每道题目的背景、实例及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode: 第 161 场周赛题解

5247. 交换字符使得字符串相同

题目

有两个长度相同的字符串 s1s2,且它们其中 只含有 字符 "x""y",你需要通过「交换字符」的方式使这两个字符串相同。
每次「交换字符」的时候,你都可以在两个字符串中各选一个字符进行交换。
交换只能发生在两个不同的字符串之间,绝对不能发生在同一个字符串内部。也就是说,我们可以交换 s1[i]s2[j],但不能交换 s1[i]s1[j]
最后,请你返回使 s1s2 相同的最小交换次数,如果没有方法能够使得这两个字符串相同,则返回 -1

实例

示例 1:

输入:s1 = “xx”, s2 = “yy”
输出:1
解释:
交换 s1[0] 和 s2[1],得到 s1 = “yx”,s2 = “yx”。

示例 2:

输入:s1 = “xy”, s2 = “yx”
输出:2
解释:
交换 s1[0] 和 s2[0],得到 s1 = “yy”,s2 = “xx” 。
交换 s1[0] 和 s2[1],得到 s1 = “xy”,s2 = “xy” 。
注意,你不能交换 s1[0] 和 s1[1] 使得 s1 变成 “yx”,因为我们只能交换属于两个不同字符串的字符。

示例 3:

输入:s1 = “xx”, s2 = “xy”
输出:-1

示例 3:

输入:s1 = “xxyyxyxyxx”, s2 = “xyyxyxxxyx”
输出:4

题解

简单题:
分三种情况

  • XYXY 交换 0
  • XXYY 交换 1
  • XYYX 交换 2
class Solution {
    public int minimumSwap(String s1, String s2) {
        char[] c = s1.toCharArray();
        char[] c1 = s2.toCharArray();
        int n = c.length;
        int []a = new int[2];
        for(int i = 0 ; i < n ; i ++) {
            a[c[i] - 'x'] ++;
            a[c1[i] - 'x'] ++;
        }
        int d1 = 0,d2 = 0;
        if(a[0] % 2 == 1 || a[1] % 2 == 1) return -1;
        for(int i = 0 ; i < n ; i ++){
            if(c[i] != c1[i]){
                if(c[i] == 'x') d1++;
                else d2 ++;
            }
        }
        int ans = 0;
        ans += d1/2;
        ans += d2/2;
        d1 = d1%2;
        d2 = d2%2;
        if(d1 == 1 && d2 == 1) ans += 2;
        return ans;
    }
}

5248. 统计优美子数组

题目

给你一个整数数组 nums和一个整数 k
如果某个子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。
请返回这个数组中「优美子数组」的数目。

实例

示例 1:

输入:nums = [1,1,2,1,1], k = 3
输出:2
解释:包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。

示例 2:

输入:nums = [2,4,6], k = 1
输出:0
解释:数列中不包含任何奇数,所以不存在优美子数组。

提示:

  • 1 <= nums.length <= 50000
  • 1 <= nums[i] <= 10^5
  • 1 <= k <= nums.length
题解

中等难度题。
首先把奇数的位置按顺序用数组a[]记录下来。
i遍历a[],第k个奇数 j = i + k - 1 包含[i,j]的优美子数组的数量:a[j + 1] - a[j] * a[i] - a[i - 1]

class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        int n = nums.length;
        int []a = new int[50001];
        int m = 0;
        int d1= 0 , d2 = 0;
        int ans = 0;
        for(int i = 0 ; i < n ; i ++) 
            if(nums[i]%2==1) a[m++] = i;
        for(int i = 0 ; i < m ; i ++){
            int j = i + k - 1;
            if(i == 0) d1 = a[i] + 1;
            else d1 = a[i] - a[i - 1];
            if(j == m - 1) d2= n - a[j];
            else d2 = a[j + 1] - a[j];
            ans += d1*d2;
        }
        return ans;
    } 
}

5249. 移除无效的括号

题目

给你一个由'('')'和小写字母组成的字符串 s。你需要从字符串中删除最少数目的'(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。请返回任意一个合法字符串。
有效「括号字符串」应当符合以下 任意一条 要求:

  • 空字符串或只包含小写字母的字符串
  • 可以被写作 ABA 连接 B)的字符串,其中 AB 都是有效「括号字符串」
  • 可以被写作 (A) 的字符串,其中 A是一个有效的「括号字符串」
示例

示例 1:

输入:s = “lee(t©o)de)”
输出:“lee(t©o)de”
解释:“lee(t(co)de)” , “lee(t©ode)” 也是一个可行答案。

示例 2:

输入:s = “a)b©d”
输出:“ab©d”

示例 3:

输入:s = “))((”
输出:""
解释:空字符串也是有效的

提示:

  • 1 <= s.length <= 10^5
  • s[i] 可能是 '('')' 或英文小写字母
题解

中等题。难度不难。

class Solution {
    public String minRemoveToMakeValid(String s) {
        char []c = s.toCharArray();
        int n = c.length;
        int d = 0;
        for(int i = 0 ; i < n ; i ++){
           if(c[i] == '(') d++;
           else if(c[i] == ')'){
               if(d == 0) c[i] = '*';
               else d --;
           }
        }
        for(int i = n - 1 ; i >= 0 && d > 0 ; i --){
            if(c[i] == '('){
                c[i] = '*';
                d --;
            }
        }
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i <  n ; i ++)
            if(c[i] != '*') sb.append(c[i]);
        return sb.toString();
    }
}

5250. 检查好数组

题目

给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。
假如该和结果为 1,那么原数组就是一个「好数组」,则返回 True;否则请返回False

示例

实例1:

输入:nums = [12,5,7,23]
输出:true
解释:挑选数字 5 和 7。
53 + 7(-2) = 1

实例2:

输入:nums = [29,6,10]
输出:true
解释:挑选数字 29, 6 和 10。
291 + 6(-3) + 10*(-1) = 1

实例3:

输入:nums = [3,6]
输出:false

提示:

1 <= nums.length <= 10^5
1 <= nums[i]<= 10^9

题解

高难度题,没做出来。
看了大神的代码,是用gcd的方法。
补充:裴蜀定理
在这里插入图片描述

class Solution {
    public boolean isGoodArray(int[] nums) {
        if(nums.length == 1)
            return nums[0] == 1;
        int a = gcd(nums[0], nums[1]);
        for(int i = 2; i < nums.length; ++i) {
            a = gcd(a, nums[i]);
            if(a == 1)
                return true;
        }
        return a == 1;
    }
    public int gcd(int p, int q) {
        if(p == 0)
            return q;
        return gcd(q % p, p);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值