分组循环A

模板

i = 0
while(i

1. LC 3011 判断一个数组是否可以变为有序

这题我比赛时用的并查集。看灵神视频学了个分组循环的做法。

对于每个分组,如果可以交换,则扩展分组的窗口,直至达到尽头或者不能交换为止。这样这个分组里的数都是可以任意交换的,因此就可以对这个分组进行排序。对每个分组排序后如果能使得整个数组有序,那么就成功。

import java.util.Arrays;

class Solution {
    public boolean canSortArray(int[] nums) {
        int i = 0;
        int start;
        int n = nums.length;
        while(inums[i]){
                return false;
            }
        }
        return true;
    }
}

2. LC 1446 连续字符

入门题。分组记录每个连续字符子串长度,维护最大值。

class Solution {
    public int maxPower(String s) {
        char[] ch = s.toCharArray();
        int i = 0;
        int n = ch.length;
        int max = 0;
        while(i

3. LC 1869 哪种连续子字符串更长

入门题。分组记录0/1子串长度,维护最大值,最后比较。

class Solution {
    public boolean checkZeroOnes(String s) {
        int max0 = 0;
        int max1 = 1;
        char[] ch = s.toCharArray();

        int i = 0;
        int n = ch.length;
        while(i< n){
            int start = i;
            char c = ch[i];
            boolean which = c =='1';
            while(imax0;
    }
}

4. LC 1957 删除字符使字符串变好

入门题。分组检查连续相同子串长度,超过2就缩减到2,拼到答案里即可。

class Solution {
    public String makeFancyString(String s) {
        char[] ch = s.toCharArray();
        StringBuilder sb = new StringBuilder();

        int i = 0;
        int n = ch.length;
        while(i

5. LC 2110 股票平滑下跌阶段的数目

入门题。分组查询每段平滑下跌阶段。贡献是(l+1)*l/2(等差数列),累加即可。

class Solution {
    public long getDescentPeriods(int[] prices) {
        int i = 0;
        int start;

        int n = prices.length;
        long ans = 0;
        while(i

6. LC 2765 最长交替子数组

每日一题+入门题。分组查询交替子数组长度,维护最大值

class Solution {
    public int alternatingSubarray(int[] nums) {
        int n = nums.length;
        int max = -1;

        int i = 0;
        int start;

        while(istart){
                max = Math.max(max,i-start+1);
            }
            if(!(i>start)){
                i++;
            }
        }

        return max;
    }
}

7. LC 228 汇总区间

入门题。分组查询递增1的区间,记录下来整合成目标格式的字符串即可。

import java.util.ArrayList;
import java.util.List;

class Solution {
    public List summaryRanges(int[] nums) {
        ArrayList> l = new ArrayList<>();

        int i = 0;
        int n = nums.length;

        while(i tmp = new ArrayList<>();
            while(i print(List> l){
        ArrayList ans = new ArrayList<>();

        for (List is : l) {
            StringBuilder sb = new StringBuilder();
            if(is.size()==1){
                sb.append(is.get(0));
            }else{
                sb.append(is.get(0)).append("->").append(is.get(is.size()-1));
            }
            ans.add(sb.toString());
        }

        return ans;
    }
}

8. LC 2760 最长奇偶子数组

入门题。分组查询满足条件的区间,维护最大值即可。

class Solution {
    public int longestAlternatingSubarray(int[] nums, int threshold) {
        int max = 0;

        int i = 0;
        int start;
        int n = nums.length;

        while(ithreshold){
                i++;
                continue;
            }

            start = i;
            while(i

9. LC 1887 使数组元素相等的减少操作次数

这道题我没想出来分组循环的写法。就想了个最好情况下O(nlgn)的散列表写法。思路大致就是,每个数最终都要等于那个最小数。每一批相同的数都要往下逐级递减。举个例子:

[ 1 1 2 2 3 3 ]

两个3要都减少到2,然后4个2减少到1。维护一个有序列表模拟这个过程即可。

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

class Solution {
    public int reductionOperations(int[] nums) {
        int ops = 0;

        // 最终都会减小到最小值
        TreeMap tm = new TreeMap<>();
        for (int num : nums) {
            mAdd(tm,num);
        }

        // 累加即可
        int prefix = 0;
        Integer[] arr = tm.keySet().toArray(Integer[]::new);
        for(int i=arr.length-1;i>=0;i--){
            prefix += tm.get(arr[i]);
            ops+=prefix;
        }

        ops-=prefix;
        return ops;
    }

    private void mAdd(Map m,int num){
        m.put(
                num,m.getOrDefault(num,0)+1
        );
    }
}

后来我发现自己sb了,这个写法完全可以改成严格的O(nlgn)的,因为减少操作的时候,跟元素的索引根本没关系。

prefix相当于每个分组到最小元素的步长。每遍历到某个分组的元素,就加上一次这个步长。如果是下一个分组就给步长+1。

import java.util.Arrays;

class Solution {
    public int reductionOperations(int[] nums) {
        int ops = 0;

        Arrays.sort(nums);
        int prefix = 0; // 相当于步长

        for(int i=1;i

10. LC 2038 如果相邻两个颜色均相同则删除当前颜色

少见的博弈类型的题。这道题比较简单,只要统计双方的可以操作的次数就可以了。可能会疑惑,有没有可能A操作完给了B新的操作机会?或者反过来,B给A机会?这是不可能的,因为要求连续子数组的数量大于等于3,所以删到长度≤2的时候就不能删了,就不可能给对方新的机会,这个≤2的子串会一直卡着对面操作。

统计操作次数很简单。分组统计连续子数组长度,为自己的操作次数贡献Math.max(0,l-2)次机会。

class Solution {
    public boolean winnerOfGame(String colors) {
        // 统计分别可以删几次就行
        int opA = 0;
        int opB = 0;

        char[] ch = colors.toCharArray();
        int n = ch.length;

        int i = 0;
        int start;

        while(i0 && opA>opB;
    }
}

11. LC 1759 统计同质子字符串的数目

入门题。查询连续相同子串的长度,计算贡献。1+2+…+l即可。

取模想不清楚?那就直接在能取模的地方全部取模,我愿称之为取模仙人。

class Solution {
    int mod = (int)1e9+7;
    public int countHomogenous(String s) {
        char[] ch = s.toCharArray();

        long ans = 0;

        int i=0;
        int start;
        int n = ch.length;

        while(i

12. LC 1578 使绳子变成彩色的最短时间

入门题。查询连续相同的子串,记录需要最长时间删除的代价,当前分组总体时间减去该最长时间即为分组的最短时间,每个分组的最短时间加起来就是总体的最短时间。

class Solution {
    public int minCost(String colors, int[] neededTime) {
        char[] ch = colors.toCharArray();

        int n = ch.length;
        int i = 0;
        int start;
        int ans = 0;

        while(i

13. LC 1839 所有元音按顺序排布的最长子字符串

入门题。对于每个分组记录长度,维护当前最大的字符,要求后续的全部大于这个字符。同时记录所有出现过的字符,如果到最后5个元音字符全部出现过,那么维护最大值。

import java.util.Arrays;
import java.util.HashSet;

class Solution {
    static char[] vowels = new char[]{'a','e','i','o','u'};
    public int longestBeautifulSubstring(String word) {
        char[] ch = word.toCharArray();
        int n = ch.length;

        int i = 0;
        int max = 0;
        while(i vs = new HashSet<>();
            int start = i;
            char last = ch[i];
            while(i=last){
                last = ch[i];
                vs.add(ch[i]);
                i++;
            }

            if(check(vs)){
                max = Math.max(max,i-start);
            }
        }
        return max;
    }

    private boolean check(HashSet vs){
        return vs.size()==5;
    }
}

你可能感兴趣的:(数据结构与算法,算法,leetcode,java)