力扣刷题记录(Java)(五)

外观数列

在这里插入图片描述

题目链接:外观数列

个人版本一(遍历)

class Solution {
    public String countAndSay(int n) {
        String str = "11", tempStr;
        if(n == 1){
            return "1";
        }
        if(n == 2){
            return "11";
        }
        int i, j, count, len;
        for( i=2 ; i<n ; i++){
            tempStr = "";
            len = str.length();
            j = 1;
            while (j<=len){
                count = 1;
                while (j < len && str.charAt(j) == str.charAt(j-1)){
                    count++;
                    j++;
                }
                tempStr += count+""+str.charAt(j-1);
                j++;
            }
            str = tempStr;
        }
        return str;
    }
}

在这里插入图片描述

官方版本一(遍历)

class Solution {
    public String countAndSay(int n) {
        String str = "1";
        for (int i = 2; i <= n; ++i) {
            StringBuilder sb = new StringBuilder();
            int start = 0;
            int pos = 0;

            while (pos < str.length()) {
                while (pos < str.length() && str.charAt(pos) == str.charAt(start)) {
                    pos++;
                }
                sb.append(Integer.toString(pos - start)).append(str.charAt(start));
                start = pos;
            }
            str = sb.toString();
        }
        
        return str;
    }
}


在这里插入图片描述

官方版本二(暴力打表)

class Solution {
    public String countAndSay(int n) {
        String[] arr = {
            "","1","11","21","1211","111221","312211","13112221","1113213211","31131211131221","13211311123113112211","11131221133112132113212221","3113112221232112111312211312113211","1321132132111213122112311311222113111221131221","11131221131211131231121113112221121321132132211331222113112211","311311222113111231131112132112311321322112111312211312111322212311322113212221","132113213221133112132113311211131221121321131211132221123113112221131112311332111213211322211312113211","11131221131211132221232112111312212321123113112221121113122113111231133221121321132132211331121321231231121113122113322113111221131221","31131122211311123113321112131221123113112211121312211213211321322112311311222113311213212322211211131221131211132221232112111312111213111213211231131122212322211331222113112211","1321132132211331121321231231121113112221121321132122311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112111331121113122112132113213211121332212311322113212221","11131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113121113123112112322111213211322211312113211","311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122211311122122111312211213211312111322211213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221131112311311121321122112132231121113122113322113111221131221","132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113213221133122112231131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211","111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121113222123112221221321132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322212321121113122123211231131122113221123113221113122112132113213211121332212311322113212221","3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211132221121311121312211213211312111322211213211321322113311213212322211231131122211311123113321112131221123113112211121312211213211321222113222112132113223113112221121113122113121113123112112322111213211322211312113211","132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113212231121113112221121321132132211231232112311321322112311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312111312212231131122211311123113322112111312211312111322111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312212221121123222112132113213221133112132123123112111311222112132113213221132213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121132211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321231231121113112221121321132122311211131122211211131221131211322113322112111312211322132113213221123113112221131112311311121321122112132231121113122113322113111221131221","1113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123211211131211121311121321123113111231131122112213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122113221122112133221121113122113121113222123211211131211121311121321123113213221121113122113121113222113221113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111221132221231221132221222112112322211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211","31131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321322123211211131211121332211231131122211311122122111312211213211312111322211231131122211311123113322112111331121113112221121113122113111231133221121113122113121113222123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221123113112221131112311332111213122112311311123112111331121113122112132113311213211321222122111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122211311123113322113223113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331221122311311222112111312211311123113322112132113213221133122211332111213112221133211322112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121122132112311321322112111312211312111322211213111213122112132113121113222112132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212311222122132113213221123113112221133112132123222112111312211312111322212321121113121112133221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213212312311211131122211213211331121321122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311222113111221221113122112132113121113222112132113213221133122211332111213322112132113213221132231131122211311123113322112111312211312111322212321121113122123211231131122113221123113221113122112132113213211121332212311322113212221","13211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221232112111312211312113211223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321322113311213212322211322132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212311222122132113213221123113112221133112132123222112111312211312111322212311322123123112111321322123122113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132132211331221122311311222112111312211311123113322112111312211312111322212311322123123112112322211211131221131211132221132213211321322113311213212322211231131122211311123113321112131221123113112211121312211213211321222113222112132113223113112221121113122113121113123112112322111213211322211312113211","11131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211132221121311121312211213211312111322211213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211211131221131211132221231122212213211321322112311311222113311213212322211211131221131211132221232112111312111213322112131112131221121321131211132221121321132132212321121113121112133221121321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122111213122112311311222113111221131221221321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111221132221231221132221222112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312111322212321121113121112133221132211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131211131221223113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112211213322112312321123113213221123113112221133112132123222112311311222113111231132231121113112221121321133112132112211213322112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311221132211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312111322212311222122132113213221123113112221133112132123222112311311222113111231133211121321132211121311121321122112133221123113112221131112311332211322111312211312111322212321121113121112133221121321132132211331121321231231121113112221121321132122311211131122211211131221131211322113322112111312211322132113213221123113112221131112311311121321122112132231121113122113322113111221131221","3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321223112111311222112132113213221133122211311221122111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331222113321112131122211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112112322211322311311222113111231133211121312211231131112311211232221121113122113121113222123211211131221132211131221121321131211132221123113112211121312211231131122113221122112133221121321132132211331121321231231121113121113122122311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312211322311211133112111312211213211311123113223112111321322123122113222122211211232221121113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123211211131211121332211213111213122112132113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231131112311311221122132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132122311211131122211213211321222113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111312211322311211133112111312212221121123222112132113213221133112132123222113223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211"
        };
        return arr[n];
    }
}

在这里插入图片描述

组合总和

在这里插入图片描述

题目链接:组合总和

个人版本一

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> list = new ArrayList<>();
        getSum(list, candidates, candidates.length-1,  0, target, new Stack<Integer>());
        return list;
    }

    public void getSum(List<List<Integer>> list, int[] candidates, int pos, int sum, int target, Stack<Integer> stack){
        while (pos >= 0){
            int now = candidates[pos];
            int all = sum + now;
            if(all < target){
                stack.push(now);
                getSum(list, candidates, pos, sum+now, target, stack);
                stack.pop();
            }else if(all == target){
                List<Integer> l = new ArrayList<>(stack);
                l.add(now);
                list.add(l);
            }
            pos--;
        }
    }
}

在这里插入图片描述

官方版本一

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }

    public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
        if (idx == candidates.length) {
            return;
        }
        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }
        // 直接跳过
        dfs(candidates, target, ans, combine, idx + 1);
        // 选择当前数
        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.remove(combine.size() - 1);
        }
    }
}


在这里插入图片描述

组合总和 II

在这里插入图片描述

题目链接:组合总和 II

个人版本一

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(candidates);
        getSum(candidates, list, target, new Stack<Integer>(), candidates.length-1,  0);
        return list;
    }
    public void getSum(int[] candidates, List<List<Integer>> list, int target, Stack<Integer> stack, int pos, int sum){
        while (pos >= 0){
            int all = sum + candidates[pos];
            if(all < target){
                stack.push(candidates[pos]);
                getSum(candidates, list, target, stack, pos-1, all);
                stack.pop();
                // 去重
                while (pos >= 1 && candidates[pos] == candidates[pos-1]){
                    pos--;
                }
            }else if(all == target){
                List<Integer> l  = new ArrayList<>(stack);
                l.add(candidates[pos]);
                list.add(l);
                // 去重
                while (pos >= 1 && candidates[pos] == candidates[pos-1]){
                    pos--;
                }
            }
            pos--;
        }
    }
}

在这里插入图片描述

官方版本一

class Solution {
    List<int[]> freq = new ArrayList<int[]>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();
    List<Integer> sequence = new ArrayList<Integer>();

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        Arrays.sort(candidates);
        for (int num : candidates) {
            int size = freq.size();
          	// 拿到所有数以及他的数量
            if (freq.isEmpty() || num != freq.get(size - 1)[0]) {
                freq.add(new int[]{num, 1});
            } else {
                ++freq.get(size - 1)[1];
            }
        }
        dfs(0, target);
        return ans;
    }
    //  整个算法逻辑是,先将数组升序,然后一直统计重复,然后在这个不含重复元素的freq列表进行操作,
    //  开始是递归到最后的数再往前回溯
     // 往前回溯的同时继续往后查找
     // 例如1,1,6,7 target=8,开始直接递归到7,往后查找,不符合,就结束
     // 往前回溯到6,6往后是7,不符合,然后往前回溯是1,1往后回溯,到6不符合,到7符合了,添加1,7
     // 通过freq中的数量去决定添加的次数,因为1的个数是2,添加了2次,所以在添加1,7后,在回溯到1的第二次循环
     // 也就添加了1,1,再往后查找,到6就符合了,添加1,1,6
     // 这样即避免了重复又达到了要求
    public void dfs(int pos, int rest) {
        if (rest == 0) {
            ans.add(new ArrayList<Integer>(sequence));
            return;
        }
        if (pos == freq.size() || rest < freq.get(pos)[0]) {
            return;
        }

        dfs(pos + 1, rest);
	    // 用于控制重复
        int most = Math.min(rest / freq.get(pos)[0], freq.get(pos)[1]);
        for (int i = 1; i <= most; ++i) {
            // 遍历操作主要使用来进一步去重处理,例如:1,1,6,7 target=8,
            // 不去重就是会有两个1,7
            sequence.add(freq.get(pos)[0]);
            dfs(pos + 1, rest - i * freq.get(pos)[0]);
        }
        for (int i = 1; i <= most; ++i) {
            sequence.remove(sequence.size() - 1);
        }
    }
}

在这里插入图片描述

其他版本一

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;

public class Solution {

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        int len = candidates.length;
        List<List<Integer>> res = new ArrayList<>();
        if (len == 0) {
            return res;
        }

        // 关键步骤
        Arrays.sort(candidates);

        Deque<Integer> path = new ArrayDeque<>(len);
        dfs(candidates, len, 0, target, path, res);
        return res;
    }

    /**
     * @param candidates 候选数组
     * @param len        冗余变量
     * @param begin      从候选数组的 begin 位置开始搜索
     * @param target     表示剩余,这个值一开始等于 target,基于题目中说明的"所有数字(包括目标数)都是正整数"这个条件
     * @param path       从根结点到叶子结点的路径
     * @param res
     */
    private void dfs(int[] candidates, int len, int begin, int target, Deque<Integer> path, List<List<Integer>> res) {
        if (target == 0) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = begin; i < len; i++) {
            // 大剪枝:减去 candidates[i] 小于 0,减去后面的 candidates[i + 1]、candidates[i + 2] 肯定也小于 0,因此用 break
            if (target - candidates[i] < 0) {
                break;
            }

            // 小剪枝:同一层相同数值的结点,从第 2 个开始,候选数更少,结果一定发生重复,因此跳过,用 continue
            if (i > begin && candidates[i] == candidates[i - 1]) {
                continue;
            }

            path.addLast(candidates[i]);
            // 调试语句 ①
            // System.out.println("递归之前 => " + path + ",剩余 = " + (target - candidates[i]));

            // 因为元素不可以重复使用,这里递归传递下去的是 i + 1 而不是 i
            dfs(candidates, len, i + 1, target - candidates[i], path, res);

            path.removeLast();
            // 调试语句 ②
            // System.out.println("递归之后 => " + path + ",剩余 = " + (target - candidates[i]));
        }
    }
}


在这里插入图片描述

接雨水

在这里插入图片描述

题目链接:接雨水

个人版本一

class Solution {
// 总思路是找打一个基点,然后往从左往右找到高度等于或大于他的块
// 找到目标块 的同时,统计中间的块数,因为宽度为1,所以高度就是块的总的占用的空间数
// 找到目标块后,计算之间的盛水总数再减去块占用的空间,就是最终的盛水总数
// 因为从左往右不一定存在大于等于该位置的块,所以需要从右往左扫描
// 从右往左扫描结束的位置,是上一次结束的位置,就是找不到存在大于等于他的块的位置
    public int trap(int[] height) {
        int len = height.length;
        if(len < 3) return 0;
        int startHeight, i = 0, j, tag = len-1, tempSum = 0, sum = 0;
        // 从左到右
        while (i < tag){
            tempSum = 0; j = i+1;
            startHeight = height[i];
            // 找到下一个高度大于等于上一个目标块的
            while (j < tag && height[j] < startHeight){
                tempSum = tempSum+height[j];
                j++;
            }
            if(j == tag && height[j] < startHeight){
                tag = i;
                break;
            }
            // 综合是两个高块之间的总量减去其中小块的量
            sum = sum + startHeight*(j-i-1)-tempSum;
            i = j;
        }
        // 从右到左
        i = len-1;
        while (i > tag && height[i] == 0){
            i--;
        }
        while (i > tag){
            tempSum = 0; j = i-1;
            startHeight = height[i];
            // 找到下一个高度大于等于上一个目标块的
            while (j > tag && height[j] < startHeight){
                tempSum = tempSum+height[j];
                j--;
            }
            if(j == tag && height[j] < startHeight){
                break;
            }
            // 综合是两个高块之间的总量减去其中小块的量
            sum = sum + startHeight*(i-j-1)-tempSum;
            i = j;
        }
        return sum;
    }
}

在这里插入图片描述

官方版本一(动态规划)

// 算法是,首先从左到右扫描,得到位置i左边最大的高度,然后从右边开始拿到位置i右边最大的高度
// 同一个位置i,这时就有了他左边最大的高度的值以及右边的最大的高度的值,在块的宽度为1的情况下,位置i盛水的高度(就是上图中位置i上有多少个那种蓝色块)
// 是取决于左右两边的最短边,因为宽度是1,所以直接拿到最短边的高度,然后直接用该高度减去位置i的高度,就能
// 拿到位置i上能盛多少水,最后加起来就是总的盛水量
class Solution {
    public int trap(int[] height) {
        int n = height.length;
        if (n == 0) {
            return 0;
        }

        int[] leftMax = new int[n];
        leftMax[0] = height[0];
        // 拿到每个位置i的左边部分最大的高度
        for (int i = 1; i < n; ++i) {
            leftMax[i] = Math.max(leftMax[i - 1], height[i]);
        }
        // 拿到每个位置i的右边部分最大的高度
        int[] rightMax = new int[n];
        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; --i) {
            rightMax[i] = Math.max(rightMax[i + 1], height[i]);
        }

        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += Math.min(leftMax[i], rightMax[i]) - height[i];
        }
        return ans;
    }
}

在这里插入图片描述

官方版本二(单调栈)

class Solution {
    public int trap(int[] height) {
        int ans = 0;
       
        Deque<Integer> stack = new LinkedList<Integer>();
        int n = height.length;
        for (int i = 0; i < n; ++i) {
        // stack的作用是拿到i两侧都比他高的块,因为两边高形成凹槽才能储水
            while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
                int top = stack.pop();
                // 这里主要用来处理现有未被处理的块中没有形成凹槽的情况,例如块的高度从小到低,那么pop以后栈就是空的
                // 如果位置i-1是比位置i要高,那么就不会进入本逻辑,而是直接走下边的push
                // 这里最终的实现结果是拿到形成凹槽的三个位置,然后进行计算他的储水量
                // 这个过程是从左到右进行,计算完一个凹槽后,再从这个凹槽的右边块开始重新找下一个凹槽
                if (stack.isEmpty()) {
                    break;
                }
                int left = stack.peek();
                int currWidth = i - left - 1;
                int currHeight = Math.min(height[left], height[i]) - height[top];
                ans += currWidth * currHeight;
            }
            stack.push(i);
        }
        return ans;
    }
}

在这里插入图片描述

官方版本三(双指针)

// 主要思想是使用双指针,两个指针指向的位置的高度,哪边矮,操作哪边
// 这是因为,假设right位置高度 > left位置高度,假设right位置高度是全局最高,那么储水量就是相当于left
// 的位置的高度,如果right位置不是最高,那么left与right之间肯定存在最高的高度,那么还是相对于left位置的高度
// 所以哪边矮操作哪边
// leftmax记录左边部分的最大高度,rightmax记录右边部分的最大高度
// 因为left是从0开始,而right是从n-1开始,那么left保持的就是各自左边部分最大的高度,leftmax就是位置
// left左边部分最大的高度
class Solution {
    public int trap(int[] height) {
        int ans = 0;
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            // 哪边小就一定哪边,假设其中一边是最高的,例如right=len-1,开始就是最高的,那么right
            // 就不会移动,left会一直移动到最后,这样就计算出每个位置left的上方存储多少水,然后累计就是总量
            // 如果right=len-1不是最高,那么首先是left移动,left肯定会移动到大于等于right的位置,该位置
            // 可能是全局最高也可能不是,但是无论是不是,只要有比right高,那么就可以进行计算right位置
            // 的储水量
            if (height[left] < height[right]) {
                ans += leftMax - height[left];
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;
    }
}

在这里插入图片描述

字符串相乘

在这里插入图片描述
题目链接:字符串相乘

个人版本一

class Solution {
    public String multiply(String num1, String num2) {
        String str = "";
        if("0".equals(num1) || "0".equals(num2)){
            return "0";
        }
        List<Integer> eleList = new ArrayList<>();
        List<Integer[]> sumList = new ArrayList<>();
        int num1Len = num1.length();
        int num2Len = num2.length();
        int flag = Integer.MAX_VALUE/10, i, j, count;
        // 保证num1是最小的
        if(num2Len < num1Len){
            return multiply(num2, num1);
        }
        int[] num2Arr = new int[num2Len];
        for(i=0; i<num2Len; i++){
            num2Arr[i] = num2.charAt(i) - '0';
        }
        // 模拟短除法
        for(i=num1Len-1; i>=0; i--){
            if(num1.charAt(i) == '0') continue;
            int toatl = 0;
            eleList.clear();
            sumList.clear();
            int k1 = num1.charAt(i) - '0';
            // 按照短除法最后一个开始乘,然后得到每一位的乘积
            for(j=0; j<num2Len; j++){
                int k2 = num2Arr[j];
                eleList.add(k1*k2);
            }
            // 处理每一位的成绩,例如88*22,首先处理出来就是[16,16],就是2和88的乘积
            j = 0;
            count = 0;
            while (j < eleList.size()){
                // 判断乘10后是否溢出,如果没有溢出就直接一般的迭代乘法
                if(toatl <= flag){
                    toatl = toatl*10 + eleList.get(j);
                    j++;
                    count++;
                }else{
                    // sumList保存eleList中添加的数不超过当前的整型最大值的最小值,也就是里边的数再乘10就会超过整型最大值
                    sumList.add(new Integer[]{toatl, count});
                    toatl = 0;
                    count = 0;
                }
            }
            sumList.add(new Integer[]{toatl, count});
            // 处理sumList里边的元素,因为都在边界,不能
            String tempStr = String.valueOf(sumList.get(0)[0]);
            // 当总和函数中只有一个,那就只有一个答案,而不需要走合并
            if(num1Len == 1 && sumList.size() == 1){
                str = tempStr;
                break;
            }

            for(j=1; j<sumList.size(); j++){
                tempStr = mergeStr(tempStr, String.valueOf(sumList.get(j)[0]), sumList.get(j)[1]);
            }
            // 处理后缀0情况
            count = num1Len-i-1;
            // 将str和tempStr合并,就是相当于完成了某一个位的运算,然后继续高位的运算
            str = mergeStr(tempStr, str, count);
        }
        return str;
    }
    // str1是高位的值,str2是低位的值
    public String mergeStr(String str1, String str2, int span){
        int end = str2.length()-span, i, j, carry = 0, k1, k2, sum;
        // 存储存在分割的字符串存在前导0导致不计算的情况
        if(end < 0){
            for(j=0; j<-end; j++){
                str2 = "0"+str2;
            }
            end = 0;
        }
        String leftPart = str2.substring(0, end);
        String rightPart = str2.substring(end);
        int leftPartLen = leftPart.length();
        String tempStr = "";
        i = leftPartLen-1;j = str1.length()-1;
        while (i>=0 && j>=0){
            k1 = str1.charAt(j) - '0';
            k2 = str2.charAt(i) - '0';
            sum = k1+k2+carry;
            tempStr =  sum%10 + tempStr;
            carry = sum/10;
            i--;
            j--;
        }
        // 存在进位
        if(carry != 0){
            // 还存在进位
            while (j>=0 && carry !=0 ){
                k1 = str1.charAt(j) - '0';
                sum = k1+carry;
                tempStr =  sum%10 + tempStr;
                carry = sum/10;
                j--;
            }
            if(carry == 1) {
                tempStr = "1"+tempStr;
            }
        }

        return str1.substring(0, j+1)+tempStr+rightPart;
    }
}

在这里插入图片描述

官方版本一(竖式加法运算)

class Solution {
	// 模仿竖式乘法,从低位开始相乘,高位末尾补零,最后相加,例如 123*23,首先是3*123=369,然后是2*123=246
	// 然后2是高位,根据他的位数给结果后补0,2在导数倒数第2位,补一个0 ,就是2460,然后369+2460,使用字符串加法算法
    public String multiply(String num1, String num2) {
        if (num1.equals("0") || num2.equals("0")) {
            return "0";
        }
        String ans = "0";
        int m = num1.length(), n = num2.length();
        for (int i = n - 1; i >= 0; i--) {
            StringBuffer curr = new StringBuffer();
            int add = 0;
            for (int j = n - 1; j > i; j--) {
                curr.append(0);
            }
            int y = num2.charAt(i) - '0';
            for (int j = m - 1; j >= 0; j--) {
                int x = num1.charAt(j) - '0';
                int product = x * y + add;
                curr.append(product % 10);
                add = product / 10;
            }
            if (add != 0) {
                curr.append(add % 10);
            }
            ans = addStrings(ans, curr.reverse().toString());
        }
        return ans;
    }

    public String addStrings(String num1, String num2) {
        int i = num1.length() - 1, j = num2.length() - 1, add = 0;
        StringBuffer ans = new StringBuffer();
        while (i >= 0 || j >= 0 || add != 0) {
            int x = i >= 0 ? num1.charAt(i) - '0' : 0;
            int y = j >= 0 ? num2.charAt(j) - '0' : 0;
            int result = x + y + add;
            ans.append(result % 10);
            add = result / 10;
            i--;
            j--;
        }
        ans.reverse();
        return ans.toString();
    }
}

在这里插入图片描述

官方版本二(竖式乘法运算)

class Solution {
// 就是把握到两数相乘的最大位数是m+n位,也就是例如2*23,1+2=3,最大就是3位,这可以证明的,m位数最大值是10^m-1
// 两个数分别有m位和n位,那这两个数的最大数相乘,(10^m-1)*(10^n-1)=10^(m+n)-10^m-10^n-1,该值比10^(m+n)要小
// 所以可以开辟一个长度为m+n的数组进行存储值,用来减少字符串运算
// 具体算法是,例如45*23,开辟长度为4的数组,从末尾开始乘,乘积放在i+j-1位置,因为该位置刚好乘出来的数的最低位对应的位置,45*23,首先是5*3=15,放在末尾,然后是5*2放在导数第二位,如此类推
// 最后得到数组是8,12,10,15,从末尾处理进位,例如15/10,结果加到前一位,余数5就是该位置的最终结果
// m+n是最多的位数,可能存在少于m+n的情况,就是m+n-1位,例如2*33,结果是0,6,6,实际上结果就是后边的66,那么就需要进一步判断
    public String multiply(String num1, String num2) {
        if (num1.equals("0") || num2.equals("0")) {
            return "0";
        }
        int m = num1.length(), n = num2.length();
        int[] ansArr = new int[m + n];
        for (int i = m - 1; i >= 0; i--) {
            int x = num1.charAt(i) - '0';
            for (int j = n - 1; j >= 0; j--) {
                int y = num2.charAt(j) - '0';
                ansArr[i + j + 1] += x * y;
            }
        }
        for (int i = m + n - 1; i > 0; i--) {
            ansArr[i - 1] += ansArr[i] / 10;
            ansArr[i] %= 10;
        }
        int index = ansArr[0] == 0 ? 1 : 0;
        StringBuffer ans = new StringBuffer();
        while (index < m + n) {
            ans.append(ansArr[index]);
            index++;
        }
        return ans.toString();
    }
}

在这里插入图片描述

通配符匹配

个人版本一(动态规划)

class Solution {
    public static boolean isMatch(String s, String p) {
        int m = s.length(), n = p.length(), i, j;
        boolean[][] f = new boolean[m+1][n+1];
        f[0][0] = true;
        // 初始化,s为空,p的*位置决定结构
        for(i=1; i<=n; i++){
            if(p.charAt(i-1) == '*'){
                f[0][i] = f[0][i-1];
            }
        }
        for(i=1; i<=m; i++){
            for(j=1; j<=n; j++){
                if(p.charAt(j-1) == '*'){
                // f[i][j-1]:不匹配的时候
                // f[i-1][j]:匹配一个或多个
                    f[i][j] = f[i][j-1] || f[i-1][j];
                }else{
                    if(p.charAt(j-1) == s.charAt(i-1) || p.charAt(j-1) == '?'){
                        f[i][j] = f[i-1][j-1];
                    }
                }
            }
        }
        return f[m][n];
    }
}

在这里插入图片描述

官方版本二(贪心算法)

// 主要思想是处理三种情况:第一种是:*v1*v2*v3*,也就是被*分割的情况,v1..可以是由小写字母以及?组成或者是空字符串,例如:p=*abc*cde*
// 因为*是可以代替任意字符的,那么我们就可以在s中找到第一个abc,然后再找到第二个cde,如果都能找到,那就说明匹配了
// 第二种是: v1*v2*,就是开头不是*,例如abc*cde*,这个时候就要严格去开头匹配abc,剩下的类似
// 第三种是:*v1*v2,也就是严格匹配末尾
// 上述三种其实还囊括了,两头都没*的情况
// 该方法比动态规划的优越在于,动态规划遍历了所有情况,而*是可以代表多个任意字符的,多个*相邻就会产生额外的空间以及无意义的操作
class Solution {
    public boolean isMatch(String s, String p) {
        int sRight = s.length(), pRight = p.length();
        // 单独处理末尾无*的情况
        while (sRight > 0 && pRight > 0 && p.charAt(pRight - 1) != '*') {
            if (charMatch(s.charAt(sRight - 1), p.charAt(pRight - 1))) {
                --sRight;
                --pRight;
            } else {
                return false;
            }
        }

        if (pRight == 0) {
            return sRight == 0;
        }
		// sIndex,
        int sIndex = 0, pIndex = 0;
        // sRecord和pRecord可以用来处理首字母不是*,然后出现匹配不相等的情况
        // 以及出现匹配重复问题,如下例子:s="abcabczzzde", p="*abc???de*"
        // 开头出现两个abc,第一个就被匹配了,实际上应该被匹配的是第二个abc
        // sRecord和pRecord就可以用来记录起始位置,sIndex和pIndex是实际操作
        // 的指针,用于贪婪匹配过程,pIndex和sIndex开始会将p开头 的abc和s开头的abc匹配
        // 而后使用sRecord以及pRecord再回到最初的位置的进行匹配,最终匹配到第二个abc
        // 往后就匹配成功了,贪婪匹配匹配到了第二个abc使得最终匹配成功

        int sRecord = -1, pRecord = -1;
        
        while (sIndex < sRight && pIndex < pRight) {
            // 处理多个*的情况
            if (p.charAt(pIndex) == '*') {
                ++pIndex;
                sRecord = sIndex;
                pRecord = pIndex;
            } else if (charMatch(s.charAt(sIndex), p.charAt(pIndex))) {
            // 处理字符匹配过程
                ++sIndex;
                ++pIndex;
            } else if (sRecord != -1 && sRecord + 1 < sRight) {
                ++sRecord;
                sIndex = sRecord;
                pIndex = pRecord;
            } else {
                return false;
            }
        }

        return allStars(p, pIndex, pRight);
    }

    public boolean allStars(String str, int left, int right) {
        for (int i = left; i < right; ++i) {
            if (str.charAt(i) != '*') {
                return false;
            }
        }
        return true;
    }

    public boolean charMatch(char u, char v) {
        return u == v || v == '?';
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值