【无标题】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

力扣周赛325前两题


ONE

题目:

给你一个下标从 0 开始的 环形 字符串数组 words 和一个字符串 target 。环形数组 意味着数组首尾相连。

形式上, words[i] 的下一个元素是 words[(i + 1) % n] ,而 words[i] 的前一个元素是 words[(i - 1 + n) % n] ,其中 n 是 words 的长度。
从 startIndex 开始,你一次可以用 1 步移动到下一个或者前一个单词。

返回到达目标字符串 target 所需的最短距离。如果 words 中不存在字符串 target ,返回 -1 。

示例:

 输入:words = ["hello","i","am","leetcode","hello"], target = "hello", startIndex = 1
输出:1
解释:从下标 1 开始,可以经由以下步骤到达 "hello" :
- 向右移动 3 个单位,到达下标 4 。
- 向左移动 2 个单位,到达下标 4 。
- 向右移动 4 个单位,到达下标 0 。
- 向左移动 1 个单位,到达下标 0 。
到达 "hello" 的最短距离是 1 。

解析:
在这里插入图片描述
代码:

class Solution {
    public int closetTarget(String[] words, String target, int startIndex) {
        // 分别向左和向右查找,比较最小值
        return Math.min(fwdLeft(words, target, startIndex), fwdRight(words, target, startIndex));
    }

    // 向左查找
    private int fwdLeft(String[] words, String target, int startIndex) {
        int step = 0;
        int[] indexArr = {startIndex, words.length - 1};
        for (int index : indexArr) {
            for (int i = index; i >= 0; i--) {
                if (words[i].equals(target)) {
                    return step;
                } else {
                    step++;
                }
            }
        }
        // un reachable
        return -1;
    }

    // 向右查找
    private int fwdRight(String[] words, String target, int startIndex) {
        int step = 0;
        int[] indexArr = {startIndex, 0};
        for (int index : indexArr) {
            for (int i = index; i < words.length; i++) {
                if (words[i].equals(target)) {
                    return step;
                } else {
                    step++;
                }
            }
        }
        // un reachable
        return -1;
    }
}

 

TWO

题目:

给你一个由字符 'a'、'b'、'c' 组成的字符串 s 和一个非负整数 k 。每分钟,你可以选择取走 s 最左侧 
还是 最右侧 的那个字符。

你必须取走每种字符 至少 k 个,返回需要的 最少 分钟数;如果无法取到,则返回 -1 。

示例:

输入:s = "aabaaaacaabc", k = 2
输出:8
解释:
从 s 的左侧取三个字符,现在共取到两个字符 'a' 、一个字符 'b' 。
从 s 的右侧取五个字符,现在共取到四个字符 'a' 、两个字符 'b' 和两个字符 'c' 。
共需要 3 + 5 = 8 分钟。
可以证明需要的最少分钟数是 8 。

解析:
不带前缀的话,从最右侧开始找有 baaaacaabc共十分钟
带前缀的话,从左侧开始找aab+caabc共八分钟
使用滑动窗口找中间最长的片段使a最多移除aCnt-k个, b最多移除bCnt-k个, c最多移除cCnt-k个
代码:

class Solution {
    public int takeCharacters(String s, int k) {
        char[] chars = s.toCharArray();
        int[] cnt = new int[3];
        for (char c : chars) {
            cnt[c - 'a']++;
        }
        if (cnt[0] < k || cnt[1] < k || cnt[2] < k) {
            return -1;
        }
        // 使用滑动窗口找中间最长的片段使a最多移除aCnt-k个, b最多移除bCnt-k个, c最多移除cCnt-k个
        int[] currentCnt = new int[3];
        int maxWindowSize = 0;
        int left = 0;
        int right = 0;
        while (left < chars.length) {
            if (right < chars.length) {
                currentCnt[chars[right++] - 'a']++;
            }
            while ((currentCnt[0] > cnt[0] - k || currentCnt[1] > cnt[1] - k || currentCnt[2] > cnt[2] - k) && left < chars.length) {
                currentCnt[chars[left++] - 'a']--;
            }
            maxWindowSize = Math.max(maxWindowSize, right - left);
            if (right == chars.length) {
                break;
            }
        }
        return s.length() - maxWindowSize;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值