[Leetcode Weekly Contest]272

链接:LeetCode

[Leetcode]2108. 找出数组中的第一个回文字符串

给你一个字符串数组 words ,找出并返回数组中的 第一个回文字符串 。如果不存在满足要求的字符串,返回一个 空字符串 "" 。

回文字符串 的定义为:如果一个字符串正着读和反着读一样,那么该字符串就是一个 回文字符串 。

遍历即可。

class Solution {
     private boolean isPalindrome(String word) {
         int start = 0, end = word.length()-1;
         while(start < end) {
             if(word.charAt(start++) != word.charAt(end--)) {
                 return false;
             }
         }
         return true;
     }

    public String firstPalindrome(String[] words) {
        for(var word:words) {
            if(isPalindrome(word)) return word;
        }
        return "";
    }
}

[Leetcode]2109. 向字符串添加空格

给你一个下标从 0 开始的字符串 s ,以及一个下标从 0 开始的整数数组 spaces 。

数组 spaces 描述原字符串中需要添加空格的下标。每个空格都应该插入到给定索引处的字符值 之前 。

例如,s = "EnjoyYourCoffee" 且 spaces = [5, 9] ,那么我们需要在 'Y' 和 'C' 之前添加空格,这两个字符分别位于下标 5 和下标 9 。因此,最终得到 "Enjoy Your Coffee" 。
请你添加空格,并返回修改后的字符串。

暴力循环即可。注意拼接String可以用StringBuilder。

class Solution {
    public String addSpaces(String s, int[] spaces) {
        int n = s.length();
        int sn = spaces.length;

        StringBuilder SB = new StringBuilder();
        int si = 0;
        int cnt = -1;
        for (int i = 0; i < n; i ++)
        {
            cnt ++;
            if (si < sn && cnt == spaces[si])
            {
                SB.append(' ');
                si ++;
            }
            SB.append(s.charAt(i));
        }
        return SB.toString();
    }
}

[Leetcode]2110. 股票平滑下跌阶段的数目

给你一个整数数组 prices ,表示一支股票的历史每日股价,其中 prices[i] 是这支股票第 i 天的价格。

一个 平滑下降的阶段 定义为:对于 连续一天或者多天 ,每日股价都比 前一日股价恰好少 1 ,这个阶段第一天的股价没有限制。

请你返回 平滑下降阶段 的数目。

动态规划,如果是平滑阶段就累加上一次的状态,否则就为1。

class Solution {
     public long getSubDesent(double steps)
     {
         return (long)(steps / 2. * (steps-1));
     }

    public long getDescentPeriods(int[] prices) {
        int step = 1;
        long res = prices.length;
        for(int ind = 1; ind < prices.length; ind ++) {
            if(prices[ind] == prices[ind-1] - 1) step ++;
            else {
                res += getSubDesent(step);
                step = 1;
            }
        }
        if(step > 1) res += getSubDesent(step);
        return res;
    }
}

[Leetcode]2111. 使数组 K 递增的最少操作次数

给你一个下标从 0 开始包含 n 个正整数的数组 arr ,和一个正整数 k 。

如果对于每个满足 k <= i <= n-1 的下标 i ,都有 arr[i-k] <= arr[i] ,那么我们称 arr 是 K 递增 的。

比方说,arr = [4, 1, 5, 2, 6, 2] 对于 k = 2 是 K 递增的,因为:
arr[0] <= arr[2] (4 <= 5)
arr[1] <= arr[3] (1 <= 2)
arr[2] <= arr[4] (5 <= 6)
arr[3] <= arr[5] (2 <= 2)
但是,相同的数组 arr 对于 k = 1 不是 K 递增的(因为 arr[0] > arr[1]),对于 k = 3 也不是 K 递增的(因为 arr[0] > arr[3] )。
每一次 操作 中,你可以选择一个下标 i 并将 arr[i] 改成任意 正整数。
请你返回对于给定的 k ,使数组变成 K 递增的 最少操作次数 。

分组+二分 O(NlogN)。
两个难点,第一个是想到求最长递增子序列。对于给定的一个序列,如果我们希望通过修改最少的元素,使得它单调递增,那么最少需要修改的元素个数,就是「序列的长度」减去「序列的最长递增子序列」的长度。
第二个是怎么求序列的最长非严格递增子序列。参考最长递增子序列, 不同的是,我们在求非严格递增子序列长度的时候,假设遍历的值为target,则二分需要找到严格大于target的值。想象这样一个例子:3331112,在循环中,如果我们替换大于等于target的值最后会出现123,无法得出长度为4的结论,理由是我们在每次加入1的时候没有替换到3的位置。相通这一点,整个算法也就很好算了。

class Solution {
    public int kIncreasing(int[] arr, int k) {
        int res = 0;
        if(k >= arr.length) return res;
        List<ArrayList<Integer>> subArray = new ArrayList<>(k);
        for(int ind=0;ind<arr.length;ind++){
            if(ind < k) subArray.add(new ArrayList<Integer>());
            int index = ind % k;
            subArray.get(index).add(arr[ind]);
        }
        for(var list:subArray) {
            res += getMinOperation(list);
        }
        return res;
    }

    private int getMinOperation(List<Integer> list) {
        List<Integer> stack = new ArrayList<>();
        int res = 0;
        for(int i=0;i<list.size();++i) {
            int target = list.get(i);
            if(stack.isEmpty() || target>=stack.get(stack.size()-1)) stack.add(target);
            else stack.set(getFirstLargerIndex(stack, target), target);
        }
        return list.size() - stack.size();
    }

    private int getFirstLargerIndex(List<Integer> nums, int target) {
        int lo = 0, hi = nums.size()-1;
        while(lo <= hi) {
            int mid = lo+(hi-lo)/2;
            if(nums.get(mid) <= target) lo = mid + 1;
            else hi = mid - 1;
        }
        return lo;
    }
}

Leetcode

posted @ 2022-04-27 09:52  Jamest  阅读(32)  评论(0编辑  收藏  举报