LeedCode 思维训练(二)

给你一个字符串 s,它由数字('0' - '9')和 '#' 组成。我们希望按下述规则将 s 映射为一些小写英文字符:

字符('a' - 'i')分别用('1' - '9')表示。
字符('j' - 'z')分别用('10#' - '26#')表示。 
返回映射之后形成的新字符串。

题目数据保证映射始终唯一。

示例 1:

输入:s = "10#11#12"
输出:"jkab"
解释:"j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".
示例 2:

输入:s = "1326#"
输出:"acz"
示例 3:

输入:s = "25#"
输出:"y"
示例 4:

输入:s = "12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"
输出:"abcdefghijklmnopqrstuvwxyz"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decrypt-string-from-alphabet-to-integer-mapping
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public class FreqAlphabets {

    public static void main(String[] args) {
        String s="12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#";
        String s1 = freqAlphabets(s);
        System.out.println(s1);
    }
    public static String freqAlphabets(String s) {
        String[] wordTable = initMapper();
        StringBuilder stringBuilder=new StringBuilder();
        while(s.length()>0){
            String origins=s;
            if(origins.length()<3){
                String subst = origins.substring(0, 1);
                String strm = wordTable[Integer.valueOf(subst)-1];
                stringBuilder.append(strm);
                s=s.substring(1);
                continue;
            }
            String substring = origins.substring(0, 3);
            if(substring.contains("#")){
                int i = origins.indexOf("#")+1;
                String substri = origins.substring(0, i);
                String index = substri.replaceAll("#", "").trim();
                Integer indexNum = Integer.valueOf(index);
                stringBuilder.append(wordTable[indexNum-1]);
                s=s.substring(i);
            }else {
                String subst = origins.substring(0, 1);
                String strm = wordTable[Integer.valueOf(subst)-1];
                stringBuilder.append(strm);
                s=s.substring(1);
            }
        }
        return stringBuilder.toString();
    }

    private static String[] initMapper() {
        String[] table={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
        return table;
    }
}

2 给你一个整数数组 nums 和一个正整数 k ,返回长度为 k 且最具 竞争力 的 nums 子序列。

数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。

在子序列 a 和子序列 b 第一个不相同的位置上,如果 a 中的数字小于 b 中对应的数字,那么我们称子序列 a 比子序列 b(相同长度下)更具 竞争力 。 例如,[1,3,4] 比 [1,3,5] 更具竞争力,在第一个不相同的位置,也就是最后一个位置上, 4 小于 5 。(未完成待更新 力扣)

示例 1:

输入:nums = [3,5,2,6], k = 2
输出:[2,6]
解释:在所有可能的子序列集合 {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]} 中,[2,6] 最具竞争力。
示例 2:

输入:nums = [2,4,3,3,5,4,9,6], k = 4
输出:[2,3,3,4]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-most-competitive-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public class MostCompetitive {
    public static void main(String[] args) {
        int[] num={71,18,52,29,55,73,24,42,66,8,80,2};
        int k=3;
        int[] ints = mostCompetitive(num, k);
        for(int i=0;i stack = new Stack<>();
        stack.add(-1);
        int len = nums.length;

        for (int i = 0; i < len; i++) {
            //当前元素比队尾元素小,将队尾元素出栈
            //此处需要另外判断数组剩余长度够不够填满栈,不然最后答案长度可能会小于k
            while (nums[i] < stack.peek() && k - stack.size() + 1 < len - i) {
                stack.pop();
            }
            if (stack.size() < k + 1) {
                stack.add(nums[i]);
            }
        }

        int[] ret = new int[k];

        while (k > 0) {
            ret[--k] = stack.pop();
        }

        return ret;
    }
}

理解题意:

子序列的定义:数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。注意:「子序列」的定义要求这些元素保持在原数组中的相对位置;
题目中「最小竞争力」的定义类似于「字典序最小」。如果做过 316. 去除重复字母 、 402. 移掉 K 位数字 和 456. 132 模式 就会知道这道问题可能需要用到「栈」。因此我们需要分许为什么解决这道问题可以用「栈」。
为什么想到用「栈」
看「示例 1」


输入:nums = [3, 5, 2, 6], k = 2
保留 2 个元素,需要移除 2 个元素。依次读入输入数组到一个线性数据结构:

读到 3,加入 3,此时 [3];
读到 5,加入 5,此时 [3, 5];
读到 2,此时 2 比之前的 5 要小,因此可以舍弃 5,这是因为 [3, 2, ...] 比 [3, 5, ...] 更具竞争力。同样地,2 比之前的 3 要小,因此可以舍弃 3,此时线性数据结构为空,加入 2。5 比 3 后加入线性数据结构,先出,恰好符合「后进先出」的规律,因此使用「栈」。
读到 6,加入 6,此时 [2, 6] 为所求。

3 给你两个图像 img1 和 img2 ,两个图像的大小都是 n x n ,用大小相同的二进制正方形矩阵表示。二进制矩阵仅由若干 0 和若干 1 组成。

转换 其中一个图像,将所有的 1 向左,右,上,或下滑动任何数量的单位;然后把它放在另一个图像的上面。该转换的 重叠 是指两个图像 都 具有 1 的位置的数目。

请注意,转换 不包括 向任何方向旋转。越过矩阵边界的 1 都将被清除。

最大可能的重叠数量是多少?(力扣)

示例 1:

LeedCode 思维训练(二)_第1张图片


输入:img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
输出:3

LeedCode 思维训练(二)_第2张图片
解释:将 img1 向右移动 1 个单位,再向下移动 1 个单位。 

两个图像都具有 1 的位置的数目是 3(用红色标识)。

示例 2:

输入:img1 = [[1]], img2 = [[1]]
输出:1
示例 3:

输入:img1 = [[0]], img2 = [[0]]
输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/image-overlap
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public class LargestOverlap {

    public static void main(String[] args) {
        int img1[][]={{0,1},{1,1}};
        int img2[][]={{1,1},{1,1}};
        int i = largestOverlap(img1, img2);
        System.out.print(i);
    }

    public static int largestOverlap(int[][] img1, int[][] img2) {
        List imgPoint1 = getImgPoint(img1);
        List imgPoint2 = getImgPoint(img2);
        if(imgPoint2.size()<=0){
            return 0;
        }

        int max=0;
        for(int k=0;k=img1.length){
                        continue;
                    }
                    if(y<0 || y>=img1[0].length){
                        continue;
                    }
                    int num=img2[x][y];
                    if(num==1){
                        count++;
                    }
                    if(count>=max){
                        max=count;
                    }
                }
            }
        }
        return max;
    }

    private static List getImgPoint(int[][] img1) {
        List imagOnePoints = new ArrayList();//点的列表
        for (int i = 0; i < img1.length; i++) {
            for (int j = 0; j < img1[0].length; j++) {
                int val = img1[i][j];
                if (val == 1) {
                    Point point = new Point(i, j);
                    imagOnePoints.add(point);
                }
            }
        }
        return imagOnePoints;
    }

    static class Point{
        private int x;
        private int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    
}

4 给你一个仅包含小写英文字母和 '?' 字符的字符串 s,请你将所有的 '?' 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。

注意:你 不能 修改非 '?' 字符。

题目测试用例保证 除 '?' 字符 之外,不存在连续重复的字符。

在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。

示例 1:

输入:s = "?zs"
输出:"azs"
解释:该示例共有 25 种解决方案,从 "azs" 到 "yzs" 都是符合题目要求的。只有 "z" 是无效的修改,因为字符串 "zzs" 中有连续重复的两个 'z' 。
示例 2:

输入:s = "ubv?w"
输出:"ubvaw"
解释:该示例共有 24 种解决方案,只有替换成 "v" 和 "w" 不符合题目要求。因为 "ubvvw" 和 "ubvww" 都包含连续重复的字符。
示例 3:

输入:s = "j?qg??b"
输出:"jaqgacb"
示例 4:

输入:s = "??yw?ipkj?"
输出:"acywaipkja"
 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;
public class ModifyString {

    public static void main(String[] args) {
        String s = "??yw?ipkj?";
        String string = modifyString(s);
        System.out.println(string);
    }

    public static String modifyString(String s) {
        Character[] table={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
        while (s.indexOf('?') != -1) {
            String insertChar = "";
            int index = s.indexOf('?');
            char before = 0;
            char after = 0;
            if (index + 1 < s.length()) {
                after = s.charAt(index + 1);
            }
            if (index - 1 >= 0) {
                before = s.charAt(index - 1);
            }
            for (int i = 0; i < table.length; i++) {
                if (before == table[i] || after == table[i]) {
                    continue;
                }
                insertChar = table[i] + "";
                break;
            }
            s = s.substring(0, index).concat(insertChar).concat(s.substring(index + 1));
        }
        return s;
    }
}

5。给定一组 N 人(编号为 1, 2, ..., N), 我们想把每个人分进任意大小的两组。

每个人都可能不喜欢其他人,那么他们不应该属于同一组。

形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。

当可以用这种方法将所有人分进两组时,返回 true;否则返回 false。

示例 1:

输入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]
示例 2:

输入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false
示例 3:

输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
输出:false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/possible-bipartition
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。(力扣 未完成)

package worn.xiao.leedcode.record2;

import java.util.*;

public class PossibleBipartition {
    public static void main(String[] args) {
        int[][] dislikes={{1,2},{1,3},{2,3}};
        boolean possibleBipartition = possibleBipartition(3, dislikes);
        System.out.println(possibleBipartition);
    }

    public static boolean possibleBipartition(int n, int[][] dislikes) {
        //1 构建一个图
        List[] graph = new ArrayList[n+1];
        Map color=new HashMap<>();

        for (int i = 1; i < graph.length; i++) {
            graph[i] = new ArrayList();
        }

        for (int i = 0; i < dislikes.length; i++) {
                int x = dislikes[i][0];
                int y = dislikes[i][1];
                graph[x].add(y);
                graph[y].add(x);
        }

        for (int point = 1; point <= n; point++) {
            if (!color.containsKey(point) && trealMap(color, point, 0, graph)) {
                return false;
            }
        }
        return true;
    }

    public static boolean trealMap(Map colorMap, Integer point, int color, List[] graph) {
        if (colorMap.containsKey(point)) {
            return colorMap.get(point) == color;
        }
        colorMap.put(point, color);

        for (int neibor : graph[point]) {
            if (!trealMap(colorMap, neibor, color ^ 1, graph)) {
                return false;
            }
        }
        return true;
    }
}

解题思路:

方法:深度优先搜索
思路

尝试将每个人分配到一个组是很自然的想法。假设第一组中的人是红色,第二组中的人是蓝色。

如果第一个人是红色的,那么这个人不喜欢的人必须是蓝色的。然后,任何不喜欢蓝色人的人都是红色的,那么任何不喜欢红色人的人都是蓝色的,依此类推。

如果在任何时候存在冲突,那么这个任务是不可能的完成的,因为从第一步开始每一步都符合逻辑。如果没有冲突,那么着色是有效的,所以答案是 true。

算法

考虑由给定的 “不喜欢” 边缘形成的 N 人的图表。我们要检查这个图的每个连通分支是否为二分的。

对于每个连通的部分,我们只需试着用两种颜色对它进行着色,就可以检查它是否是二分的。如何做到这一点:将任一结点涂成红色,然后将它的所有邻居都涂成蓝色,然后将所有的邻居的邻居都涂成红色,以此类推。如果我们将一个红色结点涂成蓝色(或蓝色结点涂成红色),那么就会产生冲突。

6  幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。

说明:解集不能包含重复的子集。

示例:

 输入: nums = [1,2,3]
 输出:

[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/power-set-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

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

public class Subsets {

    public static void main(String[] args) {
        int nums[] = {0};
        List> subsets = subsets(nums);
        for (List list:subsets) {
            System.out.println(String.valueOf(list));
        }
    }

    public static List> subsets(int[] nums) {
        List> result=new ArrayList<>();//最终结果
        List  emptySet=new ArrayList<>();
        result.add(emptySet);//先添加一个空集

        for(int i=0;i origin = result.get(j);
                List newSet=new ArrayList();
                newSet.addAll(origin);
                newSet.add(nums[i]);
                result.add(newSet);
            }
        }
        return result;
    }
}

 解题思路 

首先来看一下非递归的解题思路,比如先加入一个空集让他成为新的子集,然后每遍历一个元素就在原来的子集的后面追加这个值。还以示例来分析下

LeedCode 思维训练(二)_第3张图片

7 给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。

请你返回 words 数组中 一致字符串 的数目。

示例 1:

输入:allowed = "ab", words = ["ad","bd","aaab","baa","badab"]
输出:2
解释:字符串 "aaab" 和 "baa" 都是一致字符串,因为它们只包含字符 'a' 和 'b' 。
示例 2:

输入:allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"]
输出:7
解释:所有字符串都是一致的。
示例 3:

输入:allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"]
输出:4
解释:字符串 "cc","acd","ac" 和 "d" 是一致字符串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-the-number-of-consistent-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import java.util.*;

public class CountConsistentStrings {


    public static void main(String[] args) {
        String allowed = "exdohslrwipnt";
        String[] words = {"xrwlstne","rs","ioetdll","lwi","r","pieonois","r","xtp","stia","gicfuvmnr","hdntpxse","sodxws","v","hstirooon","d"};
        int i = countConsistentStrings(allowed, words);
        System.out.println(i);
    }

    public static int countConsistentStrings(String allowed, String[] words) {
        List stringSet=new ArrayList<>();
        for(int i=0;i

8  夏日炎炎,小男孩 Tony 想买一些雪糕消消暑。

商店中新到 n 支雪糕,用长度为 n 的数组 costs 表示雪糕的定价,其中 costs[i] 表示第 i 支雪糕的现金价格。Tony 一共有 coins 现金可以用于消费,他想要买尽可能多的雪糕。

给你价格数组 costs 和现金量 coins ,请你计算并返回 Tony 用 coins 现金能够买到的雪糕的 最大数量 。

注意:Tony 可以按任意顺序购买雪糕。

示例 1:

输入:costs = [1,3,2,4,1], coins = 7
输出:4
解释:Tony 可以买下标为 0、1、2、4 的雪糕,总价为 1 + 3 + 2 + 1 = 7
示例 2:

输入:costs = [10,6,8,7,7,8], coins = 5
输出:0
解释:Tony 没有足够的钱买任何一支雪糕。
示例 3:

输入:costs = [1,6,3,1,2,5], coins = 20
输出:6
解释:Tony 可以买下所有的雪糕,总价为 1 + 6 + 3 + 1 + 2 + 5 = 18 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-ice-cream-bars
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import java.util.Arrays;

public class MaxIceCream {
    public static void main(String[] args) {
        int[] costs = {1,6,3,1,2,5};
        int coins = 20;
        int number = maxIceCream(costs, coins);
        System.out.println(number);
    }
    
    public static int maxIceCream(int[] costs, int coins) {
        Arrays.sort(costs);
        int count = 0;
        for (int i = 0; i < costs.length; i++) {
            int cost = costs[i];
            if (coins >= cost) {
                coins = coins - cost;
                count++;
            }
        }
        return count;
    }
}

9 给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如  sqrt 。

示例 1:

输入:num = 16
输出:true
示例 2:

输入:num = 14
输出:false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-perfect-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

public class PerfectSquare {
    public static void main(String[] args) {
        System.out.println(isPerfectSquare(2000105819));
    }

    public static boolean isPerfectSquare(int num) {
        for(int i=1;i<=num;i++){
            int nu=i*i;
            if(nu==num){
                return true;
            }
            if(nu>num){
                break;
            }
        }
        return false;
    }
}

10  在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。

如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。

我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。

只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。

示例 1:


输入:root = [1,2,3,4], x = 4, y = 3
输出:false
示例 2:


输入:root = [1,2,3,null,4,null,5], x = 5, y = 4
输出:true
示例 3:

输入:root = [1,2,3,null,4], x = 2, y = 3
输出:false


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cousins-in-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 *  判断两个节点是否是堂兄弟节点
 */
public class IsCousins {

    public static void main(String[] args) {
        int[] root = {1,2,3,-1,4};
        int x = 2;
        int y = 3;
        boolean cousins = isCousins(initTree(root), x, y);
        System.out.println(cousins);
    }

    public static boolean isCousins(TreeNode root, int x, int y) {
        if (root == null) {
            return false;
        }
        TreeNode xNode = getNode(root, x);
        TreeNode yNode = getNode(root, y);
        if (xNode.high != yNode.high) {
            return false;
        }
        if (xNode.getParent().val == yNode.getParent().val) {
            return false;
        }
        return true;
    }

    /**
     * @param val
     * @return
     */
    private static TreeNode getNode(TreeNode root, int val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        TreeNode xNode = getNode(root.getLeft(), val);
        if (xNode != null) {
            return xNode;
        }
        return getNode(root.getRight(), val);
    }

    public static class TreeNode {
        int val;
        int high;
        TreeNode parent;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        public TreeNode getLeft() {
            return left;
        }

        public void setLeft(TreeNode left) {
            this.left = left;
        }

        public TreeNode getRight() {
            return right;
        }

        public void setRight(TreeNode right) {
            this.right = right;
        }

        TreeNode(int val, TreeNode parent, int high, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
            this.parent = parent;
            this.high = high;
        }


        public TreeNode getParent() {
            return parent;
        }

        public void setParent(TreeNode parent) {
            this.parent = parent;
        }

        public int getHigh() {
            return high;
        }

        public void setHigh(int high) {
            this.high = high;
        }
    }


    public static TreeNode initTree(int[] rootArray) {
        int arrayIndex = 0;
        if (rootArray.length <= 0) {
            return null;
        }
        Queue nodeQueue = new ArrayDeque<>();
        int node = rootArray[arrayIndex];
        TreeNode root = new TreeNode(node, null, 1, null, null);
        nodeQueue.add(root);

        while (!nodeQueue.isEmpty()) {
            TreeNode poll = nodeQueue.poll();
            int high = poll.getHigh();
            int leftIndex=++arrayIndex;
            if(leftIndex>=rootArray.length){
                continue;
            }
            int leftVal = rootArray[leftIndex];
            TreeNode left = new TreeNode(leftVal, poll, high + 1, null, null);
            poll.setLeft(left);
            nodeQueue.add(left);

            int rightIndex=++arrayIndex;
            if(rightIndex>=rootArray.length){
                continue;
            }

            int rightVal=rootArray[rightIndex];
            TreeNode right = new TreeNode(rightVal, poll, high + 1, null, null);
            poll.setRight(right);
            nodeQueue.add(right);
        }
        return root;
    }
}

11 给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

LeedCode 思维训练(二)_第4张图片

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]


示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]
 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-binary-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  TreeUtils.java

public class TreeUtils {
    public static TreeUtils treeUtils=null;
    
    private TreeUtils(){
        
    }
    
    public static TreeUtils getInstance(){
        if(treeUtils==null){
            synchronized (TreeUtils.class){
                if(treeUtils==null){
                    treeUtils=new TreeUtils();
                }
            }
        }
        return treeUtils;
    }

    public TreeNode initTree(Integer[] rootArray) {
        int arrayIndex = 0;
        if (rootArray.length <= 0) {
            return null;
        }
        Queue nodeQueue = new ArrayDeque<>();
        int node = rootArray[arrayIndex];
        TreeNode root = new TreeNode(node,  null, null);
        nodeQueue.add(root);

        while (!nodeQueue.isEmpty()) {
            TreeNode poll = nodeQueue.poll();
            int leftIndex=++arrayIndex;
            if(leftIndex>=rootArray.length){
                continue;
            }
            Integer leftVal = rootArray[leftIndex];
            if (leftVal != null && leftVal > 0) {
                TreeNode left = new TreeNode(leftVal, null, null);
                poll.setLeft(left);
                nodeQueue.add(left);
            }

            int rightIndex = ++arrayIndex;
            if (rightIndex >= rootArray.length) {
                continue;
            }

            Integer rightVal = rootArray[rightIndex];
            if (rightVal != null && rightVal > 0) {

                TreeNode right = new TreeNode(rightVal, null, null);
                poll.setRight(right);
                nodeQueue.add(right);
            }
        }
        return root;
    }
}

2 MergeTrees.java

package worn.xiao.leedcode.record2;

import worn.xiao.leedcode.record2.base.TreeNode;
import worn.xiao.leedcode.record2.base.TreeUtils;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class MergeTrees {
    public static void main(String[] args) {
        Integer[] root1={1};
        Integer[] root2={1,2};


        TreeNode treeNode = TreeUtils.getInstance().initTree(root1);
        TreeNode treeNode1 = TreeUtils.getInstance().initTree(root2);
        TreeNode treeNode2 = mergeTrees(treeNode, treeNode1);
        System.out.println(treeNode2);

    }

    public  static TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        List newTree=new ArrayList<>();
        List treeArrayOne=BFSTree(root1);
        List treeArrayTree=BFSTree(root2);
        int count=1;
        if (treeArrayOne.size() > treeArrayTree.size()) {
            for(int i=0;i BFSTree(TreeNode root1) {
        List  buildTree=new ArrayList<>();
        Queue treeNodeQueue=new ArrayDeque<>();
        treeNodeQueue.add(root1);
        while(!treeNodeQueue.isEmpty()){
            TreeNode poll = treeNodeQueue.poll();
            int val = poll.getVal();
            buildTree.add(val);

            TreeNode left = poll.getLeft();
            TreeNode right = poll.getRight();
            if(left!=null){
                treeNodeQueue.add(left);
            }
            if (left == null && right != null) {
                treeNodeQueue.add(new TreeNode(0));
            }

            if(right!=null){
                treeNodeQueue.add(right);
            }
        }
        return buildTree;
    }

}

   思路 通过数组的方式,用值的加法合并出一棵树来,然后再用treeUtils把数组重新转化成一棵树

12.  你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

你只有 两个 篮子,并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
你可以选择任意一棵树开始采摘,你必须从 每棵 树(包括开始采摘的树)上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。(超时)

示例 1:

输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。
示例 2:

输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
示例 3:

输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。
如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:

输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:可以采摘 [1,2,1,1,2] 这五棵树。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fruit-into-baskets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 解题思路:

  3,3,3,2,2,1--> (3,3),(2,2),(1,1) 通过标识压缩成序偶对,识别权重来解决.

package worn.xiao.leedcode.record2;

import worn.xiao.leedcode.record2.base.DataIndex;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TotalFruit {
    public static void main(String[] args) {
        int[] fruits = {1,1};
        System.out.println(totalFruit(fruits));
    }

    public static int totalFruit(int[] fruits) {
        List dataIndices = translateToNewArray(fruits);
        return calculateMaxQuality(dataIndices);
    }

    private static int calculateMaxQuality(List dataIndices) {
        int sum = 0;
        for (int i = 0; i < dataIndices.size(); i++) {
            int index = i;
            Map hashmap = new HashMap();
            while (hashmap.size() <= 2 && index < dataIndices.size()) {
                DataIndex dataIndex = dataIndices.get(index);
                Integer data = dataIndex.getData();
                Integer quality = dataIndex.getQuality();
                if(hashmap.size()>=2 && !hashmap.containsKey(data)){
                    break;
                }
                if (hashmap.containsKey(data)) {
                    Integer mapVal = hashmap.get(data);
                    quality+=mapVal;
                }
                if (hashmap.isEmpty() || hashmap.size() < 2) {
                    hashmap.put(data, quality);
                }
                index++;
            }
            int calculateSum = calculateSum(hashmap);
            if (calculateSum > sum) {
                sum = calculateSum;
            }
            hashmap.clear();
        }
        return sum;
    }

    private static int calculateSum(Map hashmap) {
        return hashmap
                .values()
                .stream()
                .mapToInt(ele -> ele)
                .sum();
    }

    private static List translateToNewArray(int[] fruits) {
        List dataIndexList = new ArrayList();
        for (int i = 0; i < fruits.length; i++) {
            int temp = fruits[i];
            int val = fruits[i];
            int count = 0;
            while (temp == val) {
                if (i >= fruits.length) {
                    break;
                }
                count++;
                i++;
                if (i < fruits.length) {
                    val = fruits[i];
                }
            }
            i--;
            DataIndex dataIndex = new DataIndex();
            dataIndex.setData(temp);
            dataIndex.setQuality(count);
            dataIndexList.add(dataIndex);
        }
        return dataIndexList;
    }
}

13 有一个具有 n个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 start 开始,到顶点 end 结束的 有效路径 。

给你数组 edges 和整数 n、start和end,如果从 start 到 end 存在 有效路径 ,则返回 true,否则返回 false 。  (正确超时)

示例 1:

LeedCode 思维训练(二)_第5张图片
输入:n = 3, edges = [[0,1],[1,2],[2,0]], start = 0, end = 2
输出:true
解释:存在由顶点 0 到顶点 2 的路径:
- 0 → 1 → 2 
- 0 → 2
示例 2:

 LeedCode 思维训练(二)_第6张图片

 
输入:n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], start = 0, end = 5
输出:false
解释:不存在由顶点 0 到顶点 5 的路径.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-if-path-exists-in-graph
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 思路 深度遍历

class Solution {
     public boolean validPath(int n, int[][] edges, int source, int destination) {
        if(n==1) return true;
        Map> maps=new HashMap<>();
        for(int i=0;i());
        }

        for(int i=0;i();
        duplimentNumber.add(source);
        return  travelIsValisd(maps,duplimentNumber,source,destination);

    }

    private Boolean travelIsValisd(Map> maps, Set duplimentNumber,int source, int destination) {
        List ally = maps.get(source);
        for(int i=0;i

14

给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。

注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-greater-element-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例 1:

输入:n = 12
输出:21

示例 2:

输入:n = 21
输出:-1
public class NextGreaterElement {
    public static void main(String[] args) {
        long indexnum = nextGreaterElement(2147483486);
        System.out.println(indexnum);
    }

    private static long nextGreaterElement(int n) {
        String str = String.valueOf(n);
        //1 获取最后一个元素
        //23175321
        //2 获取需要交换的下标
        int index = getIndexLt(str);
        //3 选择下标依次往前遍历知道大于碰到小于等于小标值的前一个进行交换
        String compareSwapStr = compareSwap(index, str);
        //4 从下标值开始逆序后面的数字
        String reverseAfter = reverseAfter(index+1, compareSwapStr);
        long revernum = Long.parseLong(reverseAfter);
        return revernum > n ? revernum : -1;
    }

    public static String compareSwap(int index, String compareSwap) {
        int numIndex = index;
        char indexNumber = compareSwap.charAt(index);
        int changeIndex = 0;
        for (int i = numIndex; i < compareSwap.length(); i++) {
            char c = compareSwap.charAt(i);
            int cIndex=i;
            if (indexNumber <= c) {
                changeIndex = cIndex;
            }
        }
        if(changeIndex>=0){
           return swap(index,changeIndex,compareSwap);
        }
        return null;
    }

    /**
     * 交换
     * @param index
     * @param changeIndex
     * @param compareSwap
     * @return
     */
    private static String swap(int index, int changeIndex, String compareSwap) {
        char[] compareSwaps = compareSwap.toCharArray();
        char tem=compareSwaps[index];
        compareSwaps[index] = compareSwaps[changeIndex];
        compareSwaps[changeIndex]=tem;
        StringBuilder str=new StringBuilder();
        for (char swap : compareSwaps) {
            str.append(swap);
        }
        return str.toString();
    }

    /**
     * 找到下标值
     * @param indexLt
     * @return
     */
    public static int getIndexLt(String indexLt) {
        int len = (indexLt.length()-1);
        while (len > 0) {
            char c = indexLt.charAt(len);
            int index = len - 1;
            char c1 = indexLt.charAt(index);
            if (c > c1) {
                return index;
            }
            len--;
        }
        return 0;
    }

    /**
     * 逆转后半段字符传
     * @param index
     * @param reverseAfter
     * @return
     */
    public static String reverseAfter(int index, String reverseAfter) {
        String prefix = reverseAfter.substring(0, index);
        String afterFix = reverseAfter.substring(index);
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(afterFix);
        StringBuilder reverse = stringBuilder.reverse();
        StringBuilder newStr=new StringBuilder();
        return newStr.append(prefix).append(reverse).toString();
    }
}

15 实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。(可以理解为字符串的模式匹配)

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。 

示例 1:

输入:haystack = "hello", needle = "ll"
输出:2
示例 2:

输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:

输入:haystack = "", needle = ""
输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-strstr
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

public class StrStr {
    public static void main(String[] args) {
        String haystack="mississippi";
        String needle="issipi";
        int strlen = strStr(haystack, needle);
        System.out.println(strlen);
    }

    public static int strStr(String haystack, String needle) {
        if(needle.length()> haystack.length()){
            return -1;
        }
        if (haystack.length() == 0) {
            return 0;
        }
        for (int i = 0; i < haystack.length(); i++) {
            int count = 0;
            int index=i;
            while (count < needle.length() && index

16  给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。(超时力扣)

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2

package worn.xiao.leedcode.record2;

public class Divide {
    public static void main(String[] args) {
        int divide = divide(-2147483648,  2);
        System.out.println(divide);
    }

    public static int divide(int dividend, int divisor) {
        int count=0;
        long newDividend = (long) dividend < 0 ? Long.parseLong(String.valueOf(dividend).substring(1)):dividend;
        int newDivisor = divisor < 0 ? -divisor : divisor;
        if (newDividend < newDivisor) { //被除数小于除数返回0
            return 0;
        }
        if(newDividend==newDivisor){
             if(getTagBit(dividend, divisor)){
                 return 1;
             }
             return -1;
        }
        if(newDivisor==1){
            if (getTagBit(dividend, divisor)) {
                if(dividend==Integer.MIN_VALUE){
                    dividend= dividend+1;
                    return dividend < 0 ? Math.abs(dividend) : dividend;
                }
                return dividend < 0 ? Math.abs(dividend) : dividend;
            }
            return dividend<0?dividend:-dividend;
        }
        while (newDividend >= newDivisor) {
            newDividend = newDividend - newDivisor;
            count++;
        }
        if(getTagBit(dividend,divisor)){
           return count;
        }
        return -count;
    }

    /**
     * 符号位
     * @param dividend
     * @param divisor
     * @return
     */
    private static Boolean getTagBit(int dividend, int divisor) {
        if(dividend <0 && divisor <0){
            return true;
        }
        if(dividend >0 && divisor >0){
            return true;
        }
        return false;
    }
}

17  给你一棵以 root 为根的二叉树,二叉树中的交错路径定义如下:

选择二叉树中 任意 节点和一个方向(左或者右)。
如果前进方向为右,那么移动到当前节点的的右子节点,否则移动到它的左子节点。
改变前进方向:左变右或者右变左。
重复第二步和第三步,直到你在树中无法继续移动。
交错路径的长度定义为:访问过的节点数目 - 1(单个节点的路径长度为 0 )。

请你返回给定树中最长 交错路径 的长度。(力扣 超时后期再优化) 

示例 1:

LeedCode 思维训练(二)_第7张图片

输入:root = [1,null,1,1,1,null,null,1,1,null,1,null,null,null,1,null,1]
输出:3
解释:蓝色节点为树中最长交错路径(右 -> 左 -> 右)。
示例 2:

LeedCode 思维训练(二)_第8张图片

输入:root = [1,1,1,null,1,null,null,1,1,null,1]
输出:4
解释:蓝色节点为树中最长交错路径(左 -> 右 -> 左 -> 右)。
示例 3:

输入:root = [1]
输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-zigzag-path-in-a-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import worn.xiao.leedcode.record2.base.TreeNode;
import worn.xiao.leedcode.record2.base.TreeUtils;

public class LongestZigZag {
    public static  int min=0;

    public static void main(String[] args) {
        Integer[] root={1};
        TreeNode treeNode = TreeUtils.getInstance().initTree(root);
        int note = longestZigZag(treeNode);
        System.out.println(note);
    }

    public static int longestZigZag(TreeNode root) {
        min=0;
        travelTree(root);
        return min;
    }

    private static void travelTree(TreeNode root) {
        if (root != null) {
            int leftLengh = leftLengh(root);
            int rightLengh = rightLengh(root);
            if (leftLengh > min) {
                min = leftLengh;
            }
            if (rightLengh > min) {
                min = rightLengh;
            }
            TreeNode left = root.getLeft();
            travelTree(left);
            TreeNode right = root.getRight();
            travelTree(right);
        }
    }

    /**
     * 左边走 交叉路径的最大长度
     * @param root
     * @return
     */
    public static int leftLengh(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int count = 0;
        TreeNode left = root.getLeft();
        if (left == null) {
            return 0;
        }
        count++;
        return count + rightLengh(left);
    }

    /**
     * 右边走 交叉路径的最大长度
     *
     * @param root
     * @return
     */
    public  static int rightLengh(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int count = 0;
        TreeNode right = root.getRight();
        if (right == null) {
            return 0;
        }
        count++;
        return count + leftLengh(right);
    }

}

18  一个 句子 指的是一个序列的单词用单个空格连接起来,且开头和结尾没有任何空格。每个单词都只包含小写或大写英文字母。

我们可以给一个句子添加 从 1 开始的单词位置索引 ,并且将句子中所有单词 打乱顺序 。

比方说,句子 "This is a sentence" 可以被打乱顺序得到 "sentence4 a3 is2 This1" 或者 "is2 sentence4 This1 a3" 。
给你一个 打乱顺序 的句子 s ,它包含的单词不超过 9 个,请你重新构造并得到原本顺序的句子。

示例 1:

输入:s = "is2 sentence4 This1 a3"
输出:"This is a sentence"
解释:将 s 中的单词按照初始位置排序,得到 "This1 is2 a3 sentence4" ,然后删除数字。
示例 2:

输入:s = "Myself2 Me1 I4 and3"
输出:"Me Myself and I"
解释:将 s 中的单词按照初始位置排序,得到 "Me1 Myself2 and3 I4" ,然后删除数字。

package worn.xiao.leedcode.record2;

import worn.xiao.leedcode.record2.base.Node;

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

public class SortSentence {
    public static void main(String[] args) {
        String s = "is2 sentence4 This1 a3";
        String s1 = sortSentence(s);
        System.out.println(s1);
    }
    
    public static String sortSentence(String s) {
        String[] words = s.split(" ");
        List worlsList=new ArrayList<>(10);
        for(String wod:words){
            String substring = wod.substring(wod.length() - 1);
            int index = Integer.parseInt(substring);
            String indexStr = wod.substring(0, wod.length() - 1);
            Node node=new Node(index,indexStr);
            worlsList.add(node);
        }
        worlsList.sort(Comparator.comparingInt(Node::getIndex));

        StringBuilder stringBuilder=new StringBuilder();
        for(Node keys:worlsList){
            stringBuilder.append(keys.getVal());
            stringBuilder.append(" ");
        }
        return stringBuilder.toString().trim();
    }
}

19 我们构建了一个包含 n 行( 索引从 1  开始 )的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。
给定行数 n 和序数 k,返回第 n 行中第 k 个字符。( k 从索引 1 开始)(力扣 超时应该用递归求解 后期优化)


示例 1:

输入: n = 1, k = 1
输出: 0
解释: 第一行:0
示例 2:

输入: n = 2, k = 1
输出: 0
解释: 
第一行: 0 
第二行: 01
示例 3:

输入: n = 2, k = 2
输出: 1
解释:
第一行: 0
第二行: 01

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/k-th-symbol-in-grammar
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import org.apache.commons.codec.binary.StringUtils;

public class KthGrammar {
    public static void main(String[] args) {
        int i = kthGrammar(30, 434991989);
        System.out.println(i);
    }
        
    public static int kthGrammar(int n, int k) {
        String finalstr=null;
        for(int i=1;i<=n;i++){
            finalstr = getTranslate(finalstr);
             if(i==1){
                 finalstr="0";
             }
        }
        char c = finalstr.charAt(k-1);
        String s = String.valueOf(c);
        return Integer.parseInt(s);
    }

    public static String getTranslate(String one){
        if(one==null){
            return null;
        }
        StringBuilder newstr=new StringBuilder();
        for(int i=0;i

20  给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。(力扣)

示例 1:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
示例 2:

输入:n = 1, k = 1
输出:[[1]]

思想:

根据搜索起点画出二叉树

既然是树形问题上的 深度优先遍历,因此首先画出树形结构。例如输入:n = 4, k = 2,我们可以发现如下递归结构:

如果组合里有 1 ,那么需要在 [2, 3, 4] 里再找 11 个数;
如果组合里有 2 ,那么需要在 [3, 4] 里再找 11数。注意:这里不能再考虑 11,因为包含 11 的组合,在第 1 种情况中已经包含。
依次类推(后面部分省略),以上描述体现的 递归 结构是:在以 nn 结尾的候选数组里,选出若干个元素。画出递归结构如下图:

LeedCode 思维训练(二)_第9张图片

说明:

      叶子结点的信息体现在从根结点到叶子结点的路径上,因此需要一个表示路径的变量 path,它是一个列表,特别地,path 是一个栈;
每一个结点递归地在做同样的事情,区别在于搜索起点,因此需要一个变量 start ,表示在区间 [begin, n] 里选出若干个数的组合;
友情提示:对于这一类问题,画图帮助分析是非常重要的解题方法。

package worn.xiao.leedcode.record2;

import com.alibaba.fastjson.JSONObject;

import java.util.*;

public class Combine {
    public static void main(String[] args) {
        List> combine = combine(1, 1);
        for (int i = 0; i < combine.size(); i++) {
            System.out.println(JSONObject.toJSONString(combine.get(i)));
        }
    }

    public static List> combine(int n, int k) {
        if (n < k) { //小于的边界
            return new ArrayList<>();
        }
        List numberList = getNList(n);
        if (n == k) { //等于的边界
            List> list = new ArrayList<>();
            list.add(numberList);
            return list;
        }
        Deque deque = new LinkedList<>();

        // 1选数 判断路径 构建节点 压栈
        // 2 出栈选数 判断路径 压榨
        structNumber(numberList, deque);
        List> finalResult = new ArrayList<>();

        while (!deque.isEmpty()) {
            Node pop = deque.pop();
            List path = pop.getPath();
            List node = pop.getNode();
            if (path.size() == k) {
                finalResult.add(path);
                continue;
            }
            for (int i = 0; i < node.size(); i++) {
                List newPath=new ArrayList<>();
                newPath.addAll(path);
                Integer nodeNum = node.get(i);
                newPath.add(nodeNum);
                Node newNode = new Node();
                newNode.setPath(newPath);
                newNode.setNode(node.subList(i+1, node.size()));
                if(newPath.size()==k){
                    finalResult.add(newPath);
                    continue;
                }
                List nod = newNode.getNode();
                if(nod.size() numberList, Deque deque) {
        for (int i = 0; i < numberList.size(); i++) {
            Integer integer = numberList.get(i);
            List numList = new ArrayList<>();
            Node node = new Node();
            node.addPath(integer);
            numList.addAll(numberList.subList(i + 1, numberList.size()));
            node.addNode(numList);
            deque.push(node);
        }
    }

    /**
     * 获取n数组
     *
     * @param n
     * @return
     */
    private static List getNList(int n) {
        List list = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        return list;
    }

    static class Node {
        private List path = new ArrayList<>();
        private List node = new ArrayList<>();

        public Node() {

        }

        public void setPath(List path) {
            this.path = path;
        }

        public void setNode(List node) {
            this.node = node;
        }

        public void addPath(Integer newPath) {
            path.add(newPath);
        }

        public List getPath() {
            return path;
        }

        public void addNode(List nodes) {
            node.addAll(nodes);
        }

        public List getNode() {
            return node;
        }
    }
}

21 给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

package worn.xiao.leedcode.record2;

import java.util.*;

public class Intersection {
    public static void main(String[] args) {
        int[] nums1={4,9,5};
        int[] nums2={9,4,9,8,4};
        int[] intersection = intersection(nums1, nums2);
        for(int i=0;i integerList = getList(nums1);
        Set setList = getList(nums2);
        integerList.retainAll(setList);

        int[] ins=new int[integerList.size()];
       int i=0;
        for(Iterator iterator = integerList.iterator();iterator.hasNext();){
            Integer next = iterator.next();
            ins[i]=next;
            i++;
        }
        return ins;
    }

    private static Set getList(int[] nums) {
        Set array=new HashSet<>();
        for(int i=0;i

22 有一个特殊打字机,它由一个 圆盘 和一个 指针 组成, 圆盘上标有小写英文字母 'a' 到 'z'。只有 当指针指向某个字母时,它才能被键入。指针 初始时 指向字符 'a' 。
每一秒钟,你可以执行以下操作之一:

LeedCode 思维训练(二)_第10张图片

每一秒钟,你可以执行以下操作之一:

将指针 顺时针 或者 逆时针 移动一个字符。
键入指针 当前 指向的字符。
给你一个字符串 word ,请你返回键入 word 所表示单词的 最少 秒数 。

示例 1:

输入:word = "abc"
输出:5
解释:
单词按如下操作键入:
- 花 1 秒键入字符 'a' in 1 ,因为指针初始指向 'a' ,故不需移动指针。
- 花 1 秒将指针顺时针移到 'b' 。
- 花 1 秒键入字符 'b' 。
- 花 1 秒将指针顺时针移到 'c' 。
- 花 1 秒键入字符 'c' 。
示例 2:

输入:word = "bza"
输出:7
解释:
单词按如下操作键入:
- 花 1 秒将指针顺时针移到 'b' 。
- 花 1 秒键入字符 'b' 。
- 花 2 秒将指针逆时针移到 'z' 。
- 花 1 秒键入字符 'z' 。
- 花 1 秒将指针顺时针移到 'a' 。
- 花 1 秒键入字符 'a' 。

示例 3:

输入:word = "zjpc"
输出:34
解释:
单词按如下操作键入:
- 花 1 秒将指针逆时针移到 'z' 。
- 花 1 秒键入字符 'z' 。
- 花 10 秒将指针顺时针移到 'j' 。
- 花 1 秒键入字符 'j' 。
- 花 6 秒将指针顺时针移到 'p' 。
- 花 1 秒键入字符 'p' 。
- 花 13 秒将指针逆时针移到 'c' 。
- 花 1 秒键入字符 'c' 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-time-to-type-word-using-special-typewriter
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

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

public class MinTimeToType {
    public static void main(String[] args) {
        String word="zjpc";
        int i = minTimeToType(word);
        System.out.println(i);
    }


    public static int minTimeToType(String word) {
        List characterList = new ArrayList<>();
        char table[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g',
                'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
                'q', 'r', 's', 't', 'u', 'v',
                'w', 'x', 'y', 'z'};

        for (int i = 0; i < table.length; i++) {
            characterList.add(table[i]);
        }
        int allStep=0;

        int point=0;
        char[] chars = word.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            int indexOf = characterList.indexOf(chars[i]);
            if(i==0 && indexOf==0){
                allStep+=point;
                allStep++;
                point=indexOf;
                continue;
            }
            int path = path(point, indexOf);
            allStep+=path;
            allStep++;
            point=indexOf;
        }
        return allStep;
    }

    private static int path(int point, int indexOf) {
        if(point < indexOf){
          return Math.min(Math.abs(point - indexOf),Math.abs(point +26- indexOf));
        }
        return Math.min(Math.abs(indexOf - point),Math.abs(indexOf +26- point));
    }
}

23 给你一个正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式。

模式 是由一个或多个值组成的子数组(连续的子序列),连续 重复多次但 不重叠 。 模式由其长度和重复次数定义。

如果数组中存在至少重复 k 次且长度为 m 的模式,则返回 true ,否则返回  false 。

示例 1:

输入:arr = [1,2,4,4,4,4], m = 1, k = 3
输出:true
解释:模式 (4) 的长度为 1 ,且连续重复 4 次。注意,模式可以重复 k 次或更多次,但不能少于 k 次。
示例 2:

输入:arr = [1,2,1,2,1,1,1,3], m = 2, k = 2
输出:true
解释:模式 (1,2) 长度为 2 ,且连续重复 2 次。另一个符合题意的模式是 (2,1) ,同样重复 2 次。
示例 3:

输入:arr = [1,2,1,2,1,3], m = 2, k = 3
输出:false
解释:模式 (1,2) 长度为 2 ,但是只连续重复 2 次。不存在长度为 2 且至少重复 3 次的模式。
示例 4:

输入:arr = [1,2,3,1,2], m = 2, k = 2
输出:false
解释:模式 (1,2) 出现 2 次但并不连续,所以不能算作连续重复 2 次。
示例 5:

输入:arr = [2,2,2,2], m = 2, k = 3
输出:false
解释:长度为 2 的模式只有 (2,2) ,但是只连续重复 2 次。注意,不能计算重叠的重复次数。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/detect-pattern-of-length-m-repeated-k-or-more-times
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 

package worn.xiao.leedcode.record2;

public class ContainsPattern {

    public static void main(String[] args) {
        int[] arr={1,2,3,1,2};
        int m=2;
        int k=2;
        boolean sk = containsPattern(arr, m, k);
        System.out.println(sk);
    }

    public static boolean containsPattern(int[] arr, int m, int k) {
        if(arr.lengthstringFromArray.length()){
                break;
            }
            String st=temp.substring(i,i+m);
            temp=temp.substring(i+m);
            int count=1;
           while(temp.startsWith(st)){
               count++;
               if(count>=k){
                   return true;
               }
               temp=temp.substring(st.length());
           }
        }
        return false;
    }

    private static String getStringFromArray(int[] arr) {
        StringBuilder stringBuilder=new StringBuilder();
        for (int j : arr) {
            stringBuilder.append(j);
        }
        return stringBuilder.toString();
    }
}

24 给你一个二维整数数组 logs ,其中每个 logs[i] = [birthi, deathi] 表示第 i 个人的出生和死亡年份。

年份 x 的 人口 定义为这一年期间活着的人的数目。第 i 个人被计入年份 x 的人口需要满足:x 在闭区间 [birthi, deathi - 1] 内。注意,人不应当计入他们死亡当年的人口中。

返回 人口最多 且 最早 的年份。

示例 1:

输入:logs = [[1993,1999],[2000,2010]]
输出:1993
解释:人口最多为 1 ,而 1993 是人口为 1 的最早年份。
示例 2:

输入:logs = [[1950,1961],[1960,1971],[1970,1981]]
输出:1960
解释: 
人口最多为 2 ,分别出现在 1960 和 1970 。
其中最早年份是 1960 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-population-year
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import java.util.*;
import java.util.stream.Collectors;

public class MaximumPopulation {

    public static void main(String[] args) {
        int[][] logs = {{1993,1999}, {2000,2010}};
        int i = maximumPopulation(logs);
        System.out.println(i);
    }

    public static int maximumPopulation(int[][] logs) {
        List persons = getPersons(logs);
        Set allAges = getAllAges(logs);
        List sortSet = allAges
                .stream()
                .sorted((o1, o2) -> o1 - o2)
                .collect(Collectors.toList());
        int min = 0;
        int time = 0;
        for(Iterator iterator=sortSet.iterator();iterator.hasNext();){
            Integer year = iterator.next();
            int count = 0;
            for (int j = 0; j < persons.size(); j++) {
                Person person = persons.get(j);
                Integer start = person.getStart();
                Integer end = person.getEnd();
                if (end >= year && start <= year) {
                    count++;
                }
            }
            if (count > min) {
                min = count;
                time = year;
            }
        }
        return time;
    }

    private static Set getAllAges(int[][] logs) {
        Set has=new HashSet<>();
        for(int i=0;i getPersons(int[][] logs) {
        List personList = new ArrayList<>();
        for (int i = 0; i < logs.length; i++) {
            int start = logs[i][0];
            int end = logs[i][1];
            end=end-1;
            personList.add(new Person(start, end));
        }
        return personList;
    }

    static class Person {
        private int start;
        private int end;

        public int getStart() {
            return start;
        }

        public void setStart(int start) {
            this.start = start;
        }

        public int getEnd() {
            return end;
        }

        public void setEnd(int end) {
            this.end = end;
        }

        public Person(int start, int end) {
            this.start = start;
            this.end = end;
        }

    }
}

 25 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/squares-of-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

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

public class SortedSquares {
    public static void main(String[] args) {
        int[] nums={-4,-1,0,3,10};
        int[] ints = sortedSquares(nums);
        for(int i=0;i  integerList=new ArrayList<>();
        for(int i=0;i o));
        int[] newNum=new int[integerList.size()];
        for(int i=0;i

26 一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组 nums ,请计算 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入:nums = [1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:

输入:nums = [2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/Gu0c2T
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

public class Rob {
    public static void main(String[] args) {
        int[] num={2,7,9,3,1};
        int rob = rob(num);
        System.out.println(rob);
    }

    public static int rob(int[] nums) {
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;
            for (int j = i; j < nums.length; j = j + 2) {
                sum += nums[j];
            }
            if (sum > max) {
                max = sum;
            }
        }
        return max;
    }
}

27 给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。

请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。

示例 1:

输入:salary = [4000,3000,1000,2000]
输出:2500.00000
解释:最低工资和最高工资分别是 1000 和 4000 。
去掉最低工资和最高工资以后的平均工资是 (2000+3000)/2= 2500
示例 2:

输入:salary = [1000,2000,3000]
输出:2000.00000
解释:最低工资和最高工资分别是 1000 和 3000 。
去掉最低工资和最高工资以后的平均工资是 (2000)/1= 2000
示例 3:

输入:salary = [6000,5000,4000,3000,2000,1000]
输出:3500.00000
示例 4:

输入:salary = [8000,9000,2000,3000,6000,1000]
输出:4750.00000

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/average-salary-excluding-the-minimum-and-maximum-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.OptionalDouble;

public class Average {

    public static void main(String[] args) {
        int[] salarys={4000,3000,1000,2000};
        double average = average(salarys);
        System.out.println(average);
    }
    public static double average(int[] salary) {
        List salarys=new ArrayList();
        for(int i=0;i o));

        salarys.remove(0);
        salarys.remove(salarys.size()-1);

        double sum = salarys
                .stream()
                .mapToDouble(item -> item)
                .sum();
        return sum/salarys.size();
    }
}

28 某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。

作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列。

例如,下表 cinema:

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   1     | War       |   great 3D   |   8.9     |
|   2     | Science   |   fiction    |   8.5     |
|   3     | irish     |   boring     |   6.2     |
|   4     | Ice song  |   Fantacy    |   8.6     |
|   5     | House card|   Interesting|   9.1     |
+---------+-----------+--------------+-----------+
对于上面的例子,则正确的输出是为:

+---------+-----------+--------------+-----------+
|   id    | movie     |  description |  rating   |
+---------+-----------+--------------+-----------+
|   5     | House card|   Interesting|   9.1     |
|   1     | War       |   great 3D   |   8.9     |
+---------+-----------+--------------+-----------+


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/not-boring-movies
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

select * from cinema where id%2=1 and description <> 'boring' order by rating desc

29 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。
示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/word-break
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

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

public class WordBreak {
    public static void main(String[] args) {
        String s="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
        List wordDict = Arrays.asList("a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa");
        boolean b = wordBreak(s, wordDict);
        System.out.println(b);
    }

    public static boolean wordBreak(String s, List wordDict) {
        if (s.length() <= 0) {
            return false;
        }
        return travel(s, wordDict);
    }

    private static boolean travel(String s, List wordDict) {
        List startWord = getStartWord(s, wordDict);
        if(startWord.size()==0){
            return false;
        }
        for (int i = 0; i < startWord.size(); i++) {
            String star = startWord.get(i);
            String startIndex = s.substring(star.length());
            if(startIndex.length()==0){
                return true;
            }
            boolean travel = travel(startIndex, wordDict);
            if(travel){
                return true;
            }
        }
        return false;
    }

    private static List getStartWord(String s, List wordDict) {
        List starts=new ArrayList();
        for(String st:wordDict){
            if(s.startsWith(st)){
                starts.add(st);
            }
        }
        return starts;
    }
}

30 给你一个字符串数组 patterns 和一个字符串 word ,统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。

子字符串 是字符串中的一个连续字符序列。

示例 1:

输入:patterns = ["a","abc","bc","d"], word = "abc"
输出:3
解释:
- "a" 是 "abc" 的子字符串。
- "abc" 是 "abc" 的子字符串。
- "bc" 是 "abc" 的子字符串。
- "d" 不是 "abc" 的子字符串。
patterns 中有 3 个字符串作为子字符串出现在 word 中。
示例 2:

输入:patterns = ["a","b","c"], word = "aaaaabbbbb"
输出:2
解释:
- "a" 是 "aaaaabbbbb" 的子字符串。
- "b" 是 "aaaaabbbbb" 的子字符串。
- "c" 不是 "aaaaabbbbb" 的字符串。
patterns 中有 2 个字符串作为子字符串出现在 word 中。
示例 3:

输入:patterns = ["a","a","a"], word = "ab"
输出:3
解释:patterns 中的每个字符串都作为子字符串出现在 word "ab" 中。


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-strings-that-appear-as-substrings-in-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;


public class NumOfStrings {
    public static void main(String[] args) {
        String[]  patterns={"a","b","c"};
        String word="aaaaabbbbb";
        int i = numOfStrings(patterns, word);
        System.out.println(i);

    }
    public static int numOfStrings(String[] patterns, String word) {
        int count=0;
        for(String papper:patterns){
           if(word.contains(papper)){
               count++;
           }
        }
        return count;
    }
}

 31 给你一个数字数组 arr 。如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为 等差数列 。如果可以重新排列数组形成等差数列,请返回 true ;否则,返回 false 。

示例 1:

输入:arr = [3,5,1]
输出:true
解释:对数组重新排序得到 [1,3,5] 或者 [5,3,1] ,任意相邻两项的差分别为 2 或 -2 ,可以形成等差数列。
示例 2:

输入:arr = [1,2,4]
输出:false
解释:无法通过重新排序得到等差数列。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/can-make-arithmetic-progression-from-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode.record2;

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

public class CanMakeArithmeticProgression {
    public static void main(String[] args) {
        int[] arr = {1,2,4};
        System.out.println(canMakeArithmeticProgression(arr));
    }

    public static boolean canMakeArithmeticProgression(int[] arr) {
        if (arr.length <= 0) {
            return false;
        }
        List arrays=new ArrayList<>();
        for(int i=0;i o));
        int vi = arrays.get(1) - arrays.get(0);
        for (int i = 0; i < arrays.size(); i++) {
            if (i + 1 < arr.length) {
                int a = arrays.get(i);
                int b = arrays.get(i+1);
                int vie = b - a;
                if (vi != vie) {
                    return false;
                }
            }
        }
        return true;
    }
}

32 给你一个整数 n ,表示比赛中的队伍数。比赛遵循一种独特的赛制:

如果当前队伍数是 偶数 ,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。
如果当前队伍数为 奇数 ,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。
返回在比赛中进行的配对次数,直到决出获胜队伍为止。

示例 1:

输入:n = 7
输出:6
解释:比赛详情:
- 第 1 轮:队伍数 = 7 ,配对次数 = 3 ,4 支队伍晋级。
- 第 2 轮:队伍数 = 4 ,配对次数 = 2 ,2 支队伍晋级。
- 第 3 轮:队伍数 = 2 ,配对次数 = 1 ,决出 1 支获胜队伍。
总配对次数 = 3 + 2 + 1 = 6
示例 2:

输入:n = 14
输出:13
解释:比赛详情:
- 第 1 轮:队伍数 = 14 ,配对次数 = 7 ,7 支队伍晋级。
- 第 2 轮:队伍数 = 7 ,配对次数 = 3 ,4 支队伍晋级。 
- 第 3 轮:队伍数 = 4 ,配对次数 = 2 ,2 支队伍晋级。
- 第 4 轮:队伍数 = 2 ,配对次数 = 1 ,决出 1 支获胜队伍。
总配对次数 = 7 + 3 + 2 + 1 = 13

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-of-matches-in-tournament
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class NumberOfMatches {
    public static void main(String[] args) {
        int i = numberOfMatches(14);
        System.out.println(i);
    }

    public static int numberOfMatches(int n) {
        int totalPairs = 0;
        while (n > 1) {
            if (n % 2 == 1) {
                int pair=(n - 1) / 2;
                n = pair + 1;
                totalPairs = totalPairs + pair;
            } else {
                int pair = n / 2;
                n=pair;
                totalPairs = totalPairs + pair;
            }
        }
        return totalPairs;
    }
}

33 给你一个整数数组 nums (下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。

比方说,如果 nums = [1,2,3] ,你可以选择增加 nums[1] 得到 nums = [1,3,3] 。
请你返回使 nums 严格递增 的 最少 操作次数。

我们称数组 nums 是 严格递增的 ,当它满足对于所有的 0 <= i < nums.length - 1 都有 nums[i] < nums[i+1] 。一个长度为 1 的数组是严格递增的一种特殊情况。

示例 1:

输入:nums = [1,1,1]
输出:3
解释:你可以进行如下操作:
1) 增加 nums[2] ,数组变为 [1,1,2] 。
2) 增加 nums[1] ,数组变为 [1,2,2] 。
3) 增加 nums[2] ,数组变为 [1,2,3] 。
示例 2:

输入:nums = [1,5,2,4,1]
输出:14
示例 3:

输入:nums = [8]
输出:0

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-operations-to-make-the-array-increasing
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class MinOperations {
    public static void main(String[] args) {
        int[] nums={1,5,2,4,1};
        int i = minOperations(nums);
        System.out.println(i);
    }

    public static int minOperations(int[] nums) {
        int sum = 0;
        for (int i = 1; i < nums.length; i++) {
            int num = nums[i];
            int before = nums[i - 1];
            if (num <= before) {
                int op = (before - num) + 1;
                sum = sum + op;
                nums[i] = before + 1;
            }
        }
        return sum;
    }
}

34 给你两个整数,n 和 start 。

数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。

请返回 nums 中所有元素按位异或(XOR)后得到的结果。

示例 1:

输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。 "^" 为按位异或 XOR 运算符。
示例 2:

输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.
示例 3:

输入:n = 1, start = 7
输出:7
示例 4:

输入:n = 10, start = 5
输出:2

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/xor-operation-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class XorOperation {
    public static void main(String[] args) {
        int n = 5, start = 0;
        int i = xorOperation(n, start);
        System.out.println(i);
    }

    public static int xorOperation(int n, int start) {
        int[] nums=new int[n];
        for(int i=0;i

35 给你一个整数 n 。按下述规则生成一个长度为 n + 1 的数组 nums :

nums[0] = 0
nums[1] = 1
当 2 <= 2 * i <= n 时,nums[2 * i] = nums[i]
当 2 <= 2 * i + 1 <= n 时,nums[2 * i + 1] = nums[i] + nums[i + 1]
返回生成数组 nums 中的 最大 值。

示例 1:

输入:n = 7
输出:3
解释:根据规则:
  nums[0] = 0
  nums[1] = 1
  nums[(1 * 2) = 2] = nums[1] = 1
  nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2
  nums[(2 * 2) = 4] = nums[2] = 1
  nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3
  nums[(3 * 2) = 6] = nums[3] = 2
  nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3
因此,nums = [0,1,1,2,1,3,2,3],最大值 3
示例 2:

输入:n = 2
输出:1
解释:根据规则,nums[0]、nums[1] 和 nums[2] 之中的最大值是 1
示例 3:

输入:n = 3
输出:2
解释:根据规则,nums[0]、nums[1]、nums[2] 和 nums[3] 之中的最大值是 2

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/get-maximum-in-generated-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int getMaximumGenerated(int n) {
        if(n==0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        int num[] = new int[n+1];
        num[0] = 0;
        num[1] = 1;
        for (int i = 2; i < n+1; i++) {
            int number = i % 2;
            if (number == 0) {
                num[i] = num[i / 2];
            } else {
                int inde = (i - number) / 2;
                num[i] = num[inde] + num[inde + 1];
            }

        }
        int max = 0;
        for (int j : num) {
            if (j > max) {
                max = j;
            }
        }
        return max;   
    }
}

36 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

LeedCode 思维训练(二)_第11张图片


输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public List inorderTraversal(TreeNode root) {
        List  nodes=new ArrayList<>();
        travelNode(root,nodes);
        return nodes;
    }

    private void travelNode(TreeNode root, List nodes) {
        if ( root != null){
            travelNode(root.left,nodes);
            nodes.add(root.val);
            travelNode(root.right,nodes);
        }
    }
}

37  给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

LeedCode 思维训练(二)_第12张图片
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
示例 4:

LeedCode 思维训练(二)_第13张图片
输入:root = [1,2]
输出:[1,2]
示例 5:

 LeedCode 思维训练(二)_第14张图片


输入:root = [1,null,2]
输出:[1,2]


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    public static List preorderTraversal(TreeNode root) {
        List result=new ArrayList<>();
        travelTree(root,result);
        return result;
    }

    private static void travelTree(TreeNode root,List result) {
        if(root !=null){
            int val = root.getVal();
            result.add(val);
            travelTree(root.getLeft(),result);
            travelTree(root.getRight(),result);
        }
    }

38 给你一个二维整数数组 ranges 和两个整数 left 和 right 。每个 ranges[i] = [starti, endi] 表示一个从 starti 到 endi 的 闭区间 。

如果闭区间 [left, right] 内每个整数都被 ranges 中 至少一个 区间覆盖,那么请你返回 true ,否则返回 false 。

已知区间 ranges[i] = [starti, endi] ,如果整数 x 满足 starti <= x <= endi ,那么我们称整数x 被覆盖了。

示例 1:

输入:ranges = [[1,2],[3,4],[5,6]], left = 2, right = 5
输出:true
解释:2 到 5 的每个整数都被覆盖了:
- 2 被第一个区间覆盖。
- 3 和 4 被第二个区间覆盖。
- 5 被第三个区间覆盖。
示例 2:

输入:ranges = [[1,10],[10,20]], left = 21, right = 21
输出:false
解释:21 没有被任何一个区间覆盖。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/check-if-all-the-integers-in-a-range-are-covered
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;
import java.util.ArrayList;
import java.util.List;

public class IsCovered {
    public static void main(String[] args) {
        int[][] ranges= new int[][]{{1,2},{3,4},{5,6}};
        int left=2;
        int right=5;
        boolean covered = isCovered(ranges, left, right);
        System.out.println(covered);
    }
    public static boolean isCovered(int[][] ranges, int left, int right) {
        List numbers = new ArrayList();
        for (int i = left; i <= right; i++) {
            numbers.add(i);
        }
        boolean result = true;
        for (Integer nu : numbers) {
            boolean isCover=false;
            for (int[] num : ranges) {
                int x = num[0];
                int y = num[1];
                if (nu >= x && nu <= y) {
                    isCover = true;
                }
            }
            if(!isCover){
                result=isCover;
            }
        }
        return result;
    }
}

39  一个班级里有 n 个学生,编号为 0 到 n - 1 。每个学生会依次回答问题,编号为 0 的学生先回答,然后是编号为 1 的学生,以此类推,直到编号为 n - 1 的学生,然后老师会重复这个过程,重新从编号为 0 的学生开始回答问题。

给你一个长度为 n 且下标从 0 开始的整数数组 chalk 和一个整数 k 。一开始粉笔盒里总共有 k 支粉笔。当编号为 i 的学生回答问题时,他会消耗 chalk[i] 支粉笔。如果剩余粉笔数量 严格小于 chalk[i] ,那么学生 i 需要 补充 粉笔。

请你返回需要 补充 粉笔的学生 编号 。

示例 1:

输入:chalk = [5,1,5], k = 22
输出:0
解释:学生消耗粉笔情况如下:
- 编号为 0 的学生使用 5 支粉笔,然后 k = 17 。
- 编号为 1 的学生使用 1 支粉笔,然后 k = 16 。
- 编号为 2 的学生使用 5 支粉笔,然后 k = 11 。
- 编号为 0 的学生使用 5 支粉笔,然后 k = 6 。
- 编号为 1 的学生使用 1 支粉笔,然后 k = 5 。
- 编号为 2 的学生使用 5 支粉笔,然后 k = 0 。
编号为 0 的学生没有足够的粉笔,所以他需要补充粉笔。
示例 2:

输入:chalk = [3,4,1,2], k = 25
输出:1
解释:学生消耗粉笔情况如下:
- 编号为 0 的学生使用 3 支粉笔,然后 k = 22 。
- 编号为 1 的学生使用 4 支粉笔,然后 k = 18 。
- 编号为 2 的学生使用 1 支粉笔,然后 k = 17 。
- 编号为 3 的学生使用 2 支粉笔,然后 k = 15 。
- 编号为 0 的学生使用 3 支粉笔,然后 k = 12 。
- 编号为 1 的学生使用 4 支粉笔,然后 k = 8 。
- 编号为 2 的学生使用 1 支粉笔,然后 k = 7 。
- 编号为 3 的学生使用 2 支粉笔,然后 k = 5 。
- 编号为 0 的学生使用 3 支粉笔,然后 k = 2 。
编号为 1 的学生没有足够的粉笔,所以他需要补充粉笔。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-student-that-will-replace-the-chalk
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class ChalkReplacer {

    public static void main(String[] args) throws IOException {
        List integerList=new ArrayList<>();
        URL resource = ChalkReplacer.class.getClassLoader().getResource("file.txt");
        String file = resource.getPath();
        BufferedReader bufferedReader=new BufferedReader(new FileReader(file));
        String line;
        while((line=bufferedReader.readLine())!=null){
            String[] split = line.split(",");
            for(int i=0;i k) {
           return getPosition(chalk, k);
        }
        long number = k % sum;
        return getPosition(chalk,number);
    }

    private static Integer getPosition(int[] chalk, long sum) {
        int result=0;
        for(int i = 0; i< chalk.length; i++){
            int number= chalk[i];
            if(sum >=number){
                sum -=number;
                if(sum<=0){
                    result=i;
                }
            }else{
                result=i;
                break;
            }
        }
        return result;
    }

    private static long getSum(int[] chalk) {
        long sum=0;
        for(int i=0;i

40 一个 句子 由一些 单词 以及它们之间的单个空格组成,句子的开头和结尾不会有多余空格。

给你一个字符串数组 sentences ,其中 sentences[i] 表示单个 句子 。

请你返回单个句子里 单词的最多数目 。

示例 1:

输入:sentences = ["alice and bob love leetcode", "i think so too", "this is great thanks very much"]
输出:6
解释:
- 第一个句子 "alice and bob love leetcode" 总共有 5 个单词。
- 第二个句子 "i think so too" 总共有 4 个单词。
- 第三个句子 "this is great thanks very much" 总共有 6 个单词。
所以,单个句子中有最多单词数的是第三个句子,总共有 6 个单词。
示例 2:

输入:sentences = ["please wait", "continue to fight", "continue to win"]
输出:3
解释:可能有多个句子有相同单词数。
这个例子中,第二个句子和第三个句子(加粗斜体)有相同数目的单词数。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-number-of-words-found-in-sentences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class MostWordsFound {

    public static void main(String[] args) {
        String[] sentences = {"alice and bob love leetcode", "i think so too", "this is great thanks very much"};
        int most=mostWordsFound(sentences);
        System.out.println(most);
    }

    public static int mostWordsFound(String[] sentences) {
        if(sentences.length<=0){
            return 0;
        }
        int max=0;
        for(int i=0;i=max){
                max=words.length;
            }
        }
        return max;
    }
}

41 编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例 1:

输入:
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出:
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]
示例 2:

输入:
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出:
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zero-matrix-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

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

public class SetZeroes {
    public static void main(String[] args) {
        int[][] matrix=new int[][]{{1,1,1},{1,0,1},{1,1,1}};
        setZeroes(matrix);
    }

    public static void setZeroes(int[][] matrix) {
      int row=matrix.length;
      int column=matrix[0].length;

      List pointList=new ArrayList<>();
      for(int i=0;i

42  给定链表头结点 head,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 nums,该列表是上述链表中整型值的一个子集。

返回列表 nums 中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表 nums 中)构成的集合。

示例 1:

LeedCode 思维训练(二)_第15张图片

输入: head = [0,1,2,3], nums = [0,1,3]
输出: 2
解释: 链表中,0 和 1 是相连接的,且 nums 中不包含 2,所以 [0, 1] 是 nums 的一个组件,同理 [3] 也是一个组件,故返回 2。
示例 2:

LeedCode 思维训练(二)_第16张图片

输入: head = [0,1,2,3,4], nums = [0,3,1,4]
输出: 2
解释: 链表中,0 和 1 是相连接的,3 和 4 是相连接的,所以 [0, 1] 和 [3, 4] 是两个组件,故返回 2。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-components (未完成)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;
import java.util.*;

public class NumComponents {

    public static void main(String[] args) {
        int[] heads={0,1,2};
        int[] nums={0,1};
        ListNode listNode=initListNode(heads);
        int i = numComponents(listNode,heads, nums);
        System.out.println(i);
    }

    private static ListNode initListNode(int[] head) {
        ListNode heads = null;
        ListNode p=null;
        for (int i = 0; i < head.length; i++) {
            int val = head[i];
            if(i==0){
                heads=new ListNode(val);
                p=heads;
                continue;
            }
            p.next=new ListNode(val);
            p=p.next;
        }
        return heads;
    }

    public static List getHeads(ListNode head){
        List heads=new ArrayList();
        while(head!=null){
            heads.add(head.val);
            head=head.next;
        }
        return heads;
    }

    public static int numComponents(ListNode head,int[] heads, int[] nums) {
        Set  alreadyCatagery=new HashSet<>();
        List> allCagary=new ArrayList<>();
        List nodeSet = getList(heads);
        List numberSet = getList(nums);
        for(int i=0;i catagery(ListNode head,Set alreadyCatagery,
                                          int num,
                                          List numberSet) {
        List  componet=new ArrayList<>();
        boolean start=false;
        for (;head != null;  head = head.next) {
            int val = head.val;
            if (val == num) {
                componet.add(num);
                alreadyCatagery.add(num);
                start=true;
                continue;
            }
            if(start && numberSet.contains(val)){
                componet.add(val);
                alreadyCatagery.add(val);
                continue;
            }
            if(start && !numberSet.contains(val)){
                break;
            }
        }
        return componet;
    }


    private static List getList(int[] nums) {
        List geli = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            geli.add(nums[i]);
        }
        return geli;
    }

    public static class ListNode {
      int val;
      ListNode next;
      ListNode() {}
      ListNode(int val) { this.val = val; }
      ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  }
}

43 给你一个整数数组 nums ,它包含 2 * n 个整数。

你需要将 nums 划分成 n 个数对,满足:

每个元素 只属于一个 数对。
同一数对中的元素 相等 。
如果可以将 nums 划分成 n 个数对,请你返回 true ,否则返回 false 。

示例 1:

输入:nums = [3,2,3,2,2,2]
输出:true
解释:
nums 中总共有 6 个元素,所以它们应该被划分成 6 / 2 = 3 个数对。
nums 可以划分成 (2, 2) ,(3, 3) 和 (2, 2) ,满足所有要求。
示例 2:

输入:nums = [1,2,3,4]
输出:false
解释:
无法将 nums 划分成 4 / 2 = 2 个数对且满足所有要求。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-array-into-equal-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

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

public class DivideArray {
    public static void main(String[] args) {
        int nums[]={1,2,3,4};
        boolean b = divideArray(nums);
        System.out.println(b);
    }

    public static boolean divideArray(int[] nums) {
        if (nums.length % 2 != 0) {
            return false;
        }
        List numbers = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            numbers.add(nums[i]);
        }
        return checkIsPaire(numbers);
    }

    private static boolean checkIsPaire(List numbers) {
        if (numbers.size() == 0) {
            return true;
        }
        Integer remove = numbers.remove(0);
        int i = numbers.indexOf(remove);
        if (i >= 0) {
            numbers.remove(i);
            return checkIsPaire(numbers);
        }
        return false;
    }
}

44  给你一个正整数 num 。你可以交换 num 中 奇偶性 相同的任意两位数字(即,都是奇数或者偶数)。

返回交换 任意 次之后 num 的 最大 可能值。

示例 1:

输入:num = 1234
输出:3412
解释:交换数字 3 和数字 1 ,结果得到 3214 。
交换数字 2 和数字 4 ,结果得到 3412 。
注意,可能存在其他交换序列,但是可以证明 3412 是最大可能值。
注意,不能交换数字 4 和数字 1 ,因为它们奇偶性不同。
示例 2:

输入:num = 65875
输出:87655
解释:交换数字 8 和数字 6 ,结果得到 85675 。
交换数字 5 和数字 7 ,结果得到 87655 。
注意,可能存在其他交换序列,但是可以证明 87655 是最大可能值。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/largest-number-after-digit-swaps-by-parity
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class LargestInteger {
    public static void main(String[] args) {
        int number=1234;
        System.out.println(largestInteger(number));
    }

    public static int largestInteger(int num) {
        String numStr = String.valueOf(num);
        char[] charArray = numStr.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            boolean isOr = charArray[i] % 2 == 0;
            for (int j = i; j < charArray.length; j++) {
                char c = charArray[j];
                boolean isOrOther = c % 2 == 0;
                if (isOr == isOrOther
                        && charArray[i] - charArray[j] < 0) {
                    char tem = charArray[i];
                    charArray[i] = charArray[j];
                    charArray[j] = tem;
                }
            }
        }
        String numbers = String.valueOf(charArray);
        return Integer.parseInt(numbers);
    }
}

45 给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。

对于每个下标 i,names[i] 和 heights[i] 表示第 i 个人的名字和身高。

请按身高 降序 顺序返回对应的名字数组 names 。

示例 1:

输入:names = ["Mary","John","Emma"], heights = [180,165,170]
输出:["Mary","Emma","John"]
解释:Mary 最高,接着是 Emma 和 John 。
示例 2:

输入:names = ["Alice","Bob","Bob"], heights = [155,185,150]
输出:["Bob","Alice","Bob"]
解释:第一个 Bob 最高,然后是 Alice 和第二个 Bob 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sort-the-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

import java.util.*;
import java.util.stream.Collectors;

public class SortPeople {
    public static void main(String[] args) {
        String[] names={"Mary","John","Emma"};
        int[] heights={180,165,170};
        String[] strings = sortPeople(names, heights);
    }

    public static String[] sortPeople(String[] names, int[] heights) {
        Map mapp = new HashMap<>();
        for (int i = 0; i < names.length; i++) {
            mapp.put(heights[i], names[i]);
        }

        List lists = mapp.keySet().stream()
                .sorted((o1, o2) -> o2-o1)
                .collect(Collectors.toList());

        List namesa = new ArrayList<>();
        for (int i = 0; i < lists.size(); i++) {
            namesa.add(mapp.get(lists.get(i)));
        }
        String[] str=new String[namesa.size()];
        namesa.toArray(str);
        return str;
    }
}

46 给你一个整数 total ,表示你拥有的总钱数。同时给你两个整数 cost1 和 cost2 ,分别表示一支钢笔和一支铅笔的价格。你可以花费你部分或者全部的钱,去买任意数目的两种笔。

请你返回购买钢笔和铅笔的 不同方案数目 。

示例 1:

输入:total = 20, cost1 = 10, cost2 = 5
输出:9
解释:一支钢笔的价格为 10 ,一支铅笔的价格为 5 。
- 如果你买 0 支钢笔,那么你可以买 0 ,1 ,2 ,3 或者 4 支铅笔。
- 如果你买 1 支钢笔,那么你可以买 0 ,1 或者 2 支铅笔。
- 如果你买 2 支钢笔,那么你没法买任何铅笔。
所以买钢笔和铅笔的总方案数为 5 + 3 + 1 = 9 种。
示例 2:

输入:total = 5, cost1 = 10, cost2 = 10
输出:1
解释:钢笔和铅笔的价格都为 10 ,都比拥有的钱数多,所以你没法购买任何文具。所以只有 1 种方案:买 0 支钢笔和 0 支铅笔。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-ways-to-buy-pens-and-pencils (超时)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class WaysToBuyPensPencils {

    public static void main(String[] args) {
        long number = waysToBuyPensPencils(1000000, 1, 1);
        System.out.println(number);
    }

    public static long waysToBuyPensPencils(int total, int cost1, int cost2) {
        int max = Math.max(cost1, cost2);
        int min = Math.min(cost1, cost2);
        int stepXLength = total / max;
        int stepYLength = total / min;
        int count = 0;
        for (int i = 0; i <= stepXLength; i++) {
            for (int j = 0; j <= stepYLength; j++) {
                int xNum = max * i;
                int yNum = total - xNum;
                if (j * min <= yNum) {
                    count++;
                }
            }
        }
        return count;
    }
}

47  有一个由小写字母组成的字符串 s,和一个长度相同的整数数组 shifts。

我们将字母表中的下一个字母称为原字母的 移位 shift() (由于字母表是环绕的, 'z' 将会变成 'a')。

例如,shift('a') = 'b', shift('t') = 'u', 以及 shift('z') = 'a'。
对于每个 shifts[i] = x , 我们会将 s 中的前 i + 1 个字母移位 x 次。

返回 将所有这些移位都应用到 s 后最终得到的字符串 。

示例 1:

输入:s = "abc", shifts = [3,5,9]
输出:"rpl"
解释: 
我们以 "abc" 开始。
将 S 中的第 1 个字母移位 3 次后,我们得到 "dbc"。
再将 S 中的前 2 个字母移位 5 次后,我们得到 "igc"。
最后将 S 中的这 3 个字母移位 9 次后,我们得到答案 "rpl"。
示例 2:

输入: s = "aaa", shifts = [1,2,3]
输出: "gfd"
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shifting-letters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class ShiftingLetters {
    public static void main(String[] args) {
       System.out.println(shiftingLetters("mkgfzkkuxownxvfvxasy",new int[]{505870226,437526072,266740649,224336793,532917782,311122363,567754492,595798950,81520022,684110326,137742843,275267355,856903962,148291585,919054234,467541837,622939912,116899933,983296461,536563513}));
    }
    public static String shiftingLetters(String s, int[] shifts) {
         String table = "abcdefghijklmnopqrstuvwxyz";
        long num[] = new long[s.toCharArray().length];

        for (int i = 0; i < num.length; i++) {
            long sum = 0;
            for (int j = i; j < shifts.length; j++) {
                sum += shifts[j];
            }
            num[i] = sum;
        }
        char[] charArray = s.toCharArray();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
            int oldIndex = table.indexOf(c);
            long newIndex = (oldIndex + num[i]) % 26;
            char[] charArray1 = table.toCharArray();
            stringBuilder.append(charArray1[Integer.valueOf(newIndex+"")]);
        }
        return stringBuilder.toString();
    }
}

48 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

示例 1:

输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
示例 2:

输入:bills = [5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/lemonade-change
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;
public class LemonadeChange {
    public static void main(String[] args) {
        int num[] = {5,5,5,10,20};
        System.out.println(lemonadeChange(num));
    }

    public static boolean lemonadeChange(int[] bills) {
        int five=0;
        int ten=0;
        for(int i=0;i0){
                   five--;
                   ten++;
                   continue;
               }else{
                   return false;
               }
           }
           if(number==20){
                if(five>0 && ten>0){
                    five--;
                    ten--;
                    continue;
                }
                if(five>=3){
                    five-=3;
                    continue;
                }
                return false;
           }
         }
        return true;
    }
}

49 给你一个下标从 0 开始的整数数组 players ,其中 players[i] 表示第 i 名运动员的 能力 值,同时给你一个下标从 0 开始的整数数组 trainers ,其中 trainers[j] 表示第 j 名训练师的 训练能力值 。

如果第 i 名运动员的能力值 小于等于 第 j 名训练师的能力值,那么第 i 名运动员可以 匹配 第 j 名训练师。除此以外,每名运动员至多可以匹配一位训练师,每位训练师最多可以匹配一位运动员。

请你返回满足上述要求 players 和 trainers 的 最大 匹配数。

示例 1:

输入:players = [4,7,9], trainers = [8,2,5,8]
输出:2
解释:
得到两个匹配的一种方案是:
- players[0] 与 trainers[0] 匹配,因为 4 <= 8 。
- players[1] 与 trainers[3] 匹配,因为 7 <= 8 。
可以证明 2 是可以形成的最大匹配数。
示例 2:

输入:players = [1,1,1], trainers = [10]
输出:1
解释:
训练师可以匹配所有 3 个运动员
每个运动员至多只能匹配一个训练师,所以最大答案是 1 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-matching-of-players-with-trainers 
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

import java.util.Arrays;

public class MatchPlayersAndTrainers {

    public static void main(String[] args) {
        int[] players = {1, 1000000000};
        int[] trainers = {1000000000, 1};
        int result = matchPlayersAndTrainers(players, trainers);
        System.out.println(result);
    }

    public static int matchPlayersAndTrainers(int[] players, int[] trainers) {
        Arrays.sort(players);
        Arrays.sort(trainers);
        int m = players.length;
        int n = trainers.length;
        int result = 0;
        for (int i = 0, j = 0; i < m && j < n; i++, j++) {
            while (j < n && players[i] > trainers[j]) {
                j++;
            }
            if (j < n) {
                result++;
            }
        }
        return result;
    }
}

50  字母序连续字符串 是由字母表中连续字母组成的字符串。换句话说,字符串 "abcdefghijklmnopqrstuvwxyz" 的任意子字符串都是 字母序连续字符串 。

例如,"abc" 是一个字母序连续字符串,而 "acb" 和 "za" 不是。
给你一个仅由小写英文字母组成的字符串 s ,返回其 最长 的 字母序连续子字符串 的长度。

示例 1:

输入:s = "abacaba"
输出:2
解释:共有 4 个不同的字母序连续子字符串 "a"、"b"、"c" 和 "ab" 。
"ab" 是最长的字母序连续子字符串。
示例 2:

输入:s = "abcde"
输出:5
解释:"abcde" 是最长的字母序连续子字符串。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/length-of-the-longest-alphabetical-continuous-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

package worn.xiao.leedcode;

public class LongestContinuousSubstring {
    public static void main(String[] args) {
        String str = "abcde";
        System.out.println(longestContinuousSubstring(str));
    }

    public static int longestContinuousSubstring(String str) {
        char[] chars = str.toCharArray();
        if (chars.length == 0) {
            return 0;
        }
        int result = 0;
        for (int i = 0; i < chars.length; i++) {
            int count = 1;
            for (int j = i; j < chars.length; j++) {
                int number = j + 1;
                if (number == chars.length) {
                    continue;
                }
                char aChar = chars[j];
                char aChar1 = chars[number];
                if (aChar1 - aChar != 1) {
                    break;
                }
                count++;
            }
            if (count > result) {
                result = count;
            }
        }
        return result;
    }
}

你可能感兴趣的:(算法/数据结构与算法,蓝桥杯,算法,leetcode,1024程序员节)