zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java每日一练(20230319)

JAVA 每日
2023-09-14 09:01:29 时间

目录

1. 最大矩形  🌟🌟🌟

2. 回文对  🌟🌟🌟

3. 给表达式添加运算符  🌟🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


1. 最大矩形

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = []
输出:0

示例 3:

输入:matrix = [["0"]]
输出:0

示例 4:

输入:matrix = [["1"]]
输出:1

示例 5:

输入:matrix = [["0","0"]]
输出:0

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 0 <= row, cols <= 200
  • matrix[i][j] 为 '0' 或 '1'

出处:

https://edu.csdn.net/practice/23165386

代码:

import java.util.List;
import java.util.Arrays;
public class maxRectangle {
    public static class Solution {
        public int maximalRectangle(char[][] matrix) {
            if (matrix == null || matrix.length == 0)
                return 0;
            int m = matrix.length;
            int n = matrix[0].length;
            int[] left = new int[n];
            int[] right = new int[n];
            int[] height = new int[n];
            Arrays.fill(right, n);
            int cur_left = 0;
            int cur_right = n;
            int res = 0;
            for (int i = 0; i < m; i++) {
                cur_left = 0;
                cur_right = n;
                for (int j = 0; j < n; j++) {
                    if (matrix[i][j] == '1')
                        height[j]++;
                    else
                        height[j] = 0;
                }
                for (int j = 0; j < n; j++) {
                    if (matrix[i][j] == '1') {
                        left[j] = Math.max(left[j], cur_left);
                    } else {
                        left[j] = 0;
                        cur_left = j + 1;
                    }
                }
                for (int j = n - 1; j >= 0; j--) {
                    if (matrix[i][j] == '1') {
                        right[j] = Math.min(right[j], cur_right);
                    } else {
                        right[j] = n;
                        cur_right = j;
                    }
                }
                for (int j = 0; j < n; j++)
                    res = Math.max(res, (right[j] - left[j]) * height[j]);
                }
            return res;
        }
    }

    public static void main(String[] args) {
        Solution s = new Solution();
        char[][] matrix = {{'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'}};
        System.out.println(s.maximalRectangle(matrix));
    }
}

输出:

6

import java.util.Deque;
import java.util.LinkedList;
public class maxRectangle {
    public static class Solution {
        public int maximalRectangle(char[][] matrix) {
            if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return 0;
            }
            int m = matrix.length, n = matrix[0].length;
            int[] heights = new int[n];
            int ans = 0;
            for (int i = 0; i < m; ++i) {
                // 更新高度数组
                for (int j = 0; j < n; ++j) {
                    if (matrix[i][j] == '1') {
                        heights[j] += 1;
                    } else {
                        heights[j] = 0;
                    }
                }
                // 计算最大矩形面积
                ans = Math.max(ans, largestRectangleArea(heights));
            }
            return ans;
        }
        private int largestRectangleArea(int[] heights) {
            int n = heights.length;
            int[] left = new int[n];
            int[] right = new int[n];
            Deque<Integer> stack = new LinkedList<>();
            // 计算 left 数组
            for (int i = 0; i < n; ++i) {
                while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                    stack.pop();
                }
                left[i] = stack.isEmpty() ? -1 : stack.peek();
                stack.push(i);
            }
            stack.clear();
            // 计算 right 数组
            for (int i = n - 1; i >= 0; --i) {
                while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
                    stack.pop();
                }
                right[i] = stack.isEmpty() ? n : stack.peek();
                stack.push(i);
            }
            // 计算最大矩形面积
            int ans = 0;
            for (int i = 0; i < n; ++i) {
                ans = Math.max(ans, heights[i] * (right[i] - left[i] - 1));
            }
            return ans;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        char[][] matrix = {{'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'}};
        System.out.println(s.maximalRectangle(matrix));
    }
}

用一个一维数组 heights 来记录当前行中以每个元素为底的最大连续 1 的个数。

然后,对每一行都计算其最大矩形面积,并更新答案。

计算最大矩形面积的算法如下:

定义一个栈 stack 和两个数组 left 和 right,其中 left[i] 表示第 i 个元素左边第一个小于它的元素的下标,right[i] 表示第 i 个元素右边第一个小于它的元素的下标;

1. 从左到右遍历 heights 数组,对每个元素 heights[i],执行以下操作:

如果栈为空或者栈顶元素对应的高度小于等于当前元素的高度,则将当前元素的下标入栈;
否则,弹出栈顶元素,更新 left[i] 为栈顶元素的下标,直到栈为空或者栈顶元素对应的高度小于当前元素的高度,然后将当前元素的下标入栈;

2. 从右到左遍历 heights 数组,对每个元素 heights[i],执行以下操作:

如果栈为空或者栈顶元素对应的高度小于等于当前元素的高度,则将当前元素的下标入栈;
否则,弹出栈顶元素,更新 right[i] 为栈顶元素的下标,直到栈为空或者栈顶元素对应的高度小于当前元素的高度,然后将当前元素的下标入栈;

3. 最后,遍历 heights 数组,计算每个元素对应的最大矩形面积 heights[i] * (right[i] - left[i] - 1),并更新答案; 返回答案。


2. 回文对

给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。

示例 1:

输入:words = ["abcd","dcba","lls","s","sssll"]
输出:[[0,1],[1,0],[3,2],[2,4]] 
解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]

示例 2:

输入:words = ["bat","tab","cat"]
输出:[[0,1],[1,0]] 
解释:可拼接成的回文串为 ["battab","tabbat"]

示例 3:

输入:words = ["a",""]
输出:[[0,1],[1,0]]

提示:

  • 1 <= words.length <= 5000
  • 0 <= words[i].length <= 300
  • words[i] 由小写英文字母组成

出处:

https://edu.csdn.net/practice/23165387

代码1:

import java.util.*;
public class palindromePairs {
    public static class Solution {
        private static List<List<Integer>> ans = new ArrayList<>();
        public List<List<Integer>> palindromePairs(String[] words) {
            if (words == null || words.length == 0) {
                return null;
            }
            ans = new ArrayList<>();
            TrieNode root = new TrieNode();
            for (int i = 0; i < words.length; i++) {
                addWord(root, words[i], i);
            }
            for (int i = 0; i < words.length; i++) {
                find(root, words[i], i);
            }
            return ans;
        }
        private static class TrieNode {
            int index;
            TrieNode[] next;
            List<Integer> palindIndex;
            public TrieNode() {
                index = -1;
                next = new TrieNode[26];
                palindIndex = new ArrayList<>();
            }
        }
        private static void addWord(TrieNode root, String word, int index) {
            for (int i = word.length() - 1; i >= 0; i--) {
                int ch = word.charAt(i) - 'a';
                if (root.next[ch] == null) {
                    root.next[ch] = new TrieNode();
                }
                if (isPalindrome(word, 0, i)) {
                    root.palindIndex.add(index);
                }
                root = root.next[ch];
            }
            root.index = index;
            root.palindIndex.add(index);
        }
        private static void find(TrieNode root, String word, int index) {
            for (int i = 0; i < word.length(); i++) {
                if (root.index != -1 && root.index != index && isPalindrome(word, i, word.length() - 1)) {
                    ans.add(Arrays.asList(index, root.index));
                }
                if (root.next[word.charAt(i) - 'a'] == null) {
                    return;
                }
                root = root.next[word.charAt(i) - 'a'];
            }
            for (int i : root.palindIndex) {
                if (i != index) {
                    ans.add(Arrays.asList(index, i));
                }
            }
        }
        private static boolean isPalindrome(String string, int l, int r) {
            while (l < r) {
                if (string.charAt(l++) != string.charAt(r--)) {
                    return false;
                }
            }
            return true;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        String[] words = {"abcd","dcba","lls","s","sssll"};
        System.out.println(s.palindromePairs(words));

        String[] words1 = {"bat","tab","cat"};
        System.out.println(s.palindromePairs(words1));

        String[] words2 = {"a",""};
        System.out.println(s.palindromePairs(words2));
    }
}

输出:

[[0, 1], [1, 0], [2, 4], [3, 2]]
[[0, 1], [1, 0]]
[[0, 1], [1, 0]]

代码2:

思路:遍历单词列表,对于每个单词,将其拆分成左右两个部分,如果左边是回文串,那么找右边的逆序单词是否在单词列表中,如果在,则说明当前单词可以和右边的逆序单词拼接成回文串。同理,如果右边是回文串,那么找左边的逆序单词是否在单词列表中。

import java.util.*;
public class palindromePairs {
    public static class Solution {
        public List<List> palindromePairs(String[] words) {
            List<List> res = new ArrayList<>();
            if (words == null || words.length < 2) return res;
            Map<String, Integer> map = new HashMap<>();
            for (int i = 0; i < words.length; i++) {
                map.put(words[i], i);
            }
            for (int i = 0; i < words.length; i++) {
                String word = words[i];
                for (int j = 0; j <= word.length(); j++) {
                    String left = word.substring(0, j);
                    String right = word.substring(j);
                    if (isPalindrome(left)) {
                        String reverseRight = new StringBuilder(right).reverse().toString();
                        if (map.containsKey(reverseRight) && map.get(reverseRight) != i) {
                            res.add(Arrays.asList(map.get(reverseRight), i));
                        }
                    }
                    if (isPalindrome(right)) {
                        String reverseLeft = new StringBuilder(left).reverse().toString();
                        if (map.containsKey(reverseLeft) && map.get(reverseLeft) != i && right.length() != 0) {
                            res.add(Arrays.asList(i, map.get(reverseLeft)));
                        }
                    }
                }
            }
            return res;
        }
        private boolean isPalindrome(String s) {
            int left = 0, right = s.length() - 1;
            while (left < right) {
                if (s.charAt(left) != s.charAt(right)) {
                    return false;
                }
                left++;
                right--;
            }
            return true;
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        String[] words = {"abcd","dcba","lls","s","sssll"};
        System.out.println(s.palindromePairs(words));

        String[] words1 = {"bat","tab","cat"};
        System.out.println(s.palindromePairs(words1));

        String[] words2 = {"a",""};
        System.out.println(s.palindromePairs(words2));
    }
}

输出:

[[1, 0], [0, 1], [3, 2], [2, 4]]
[[1, 0], [0, 1]]
[[0, 1], [1, 0]]


3. 给表达式添加运算符

给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)+- 或 * ,返回所有能够得到目标值的表达式。

示例 1:

输入: num = "123", target = 6
输出: ["1+2+3", "1*2*3"] 

示例 2:

输入: num = "232", target = 8
输出: ["2*3+2", "2+3*2"]

示例 3:

输入: num = "105", target = 5
输出: ["1*0+5","10-5"]

示例 4:

输入: num = "00", target = 0
输出: ["0+0", "0-0", "0*0"]

示例 5:

输入: num = "3456237490", target = 9191
输出: []

提示:

  • 1 <= num.length <= 10
  • num 仅含数字
  • -2^31 <= target <= 2^31 - 1

出处:

https://edu.csdn.net/practice/23165388

代码1:

import java.util.*;
public class addOperators {
    public static class Solution {
        int n;
        String num;
        List<String> ans;
        int target;
        public List<String> addOperators(String num, int target) {
            this.n = num.length();
            this.num = num;
            this.target = target;
            this.ans = new ArrayList<String>();
            StringBuffer expr = new StringBuffer();
            dfs(expr, 0, 0, 0);
            return ans;
        }
        private void dfs(StringBuffer sba, long sum, long prepareMultiply, int index) {
            StringBuffer sb = new StringBuffer(sba);
            if (index == n) {
                if (sum == target) {
                    ans.add(sb.toString());
                }
                return;
            }
            int sign = sb.length();
            if (index > 0) {
                sb.append("0");
            }
            long val = 0;
            for (int i = index; i < n && (i == index || num.charAt(index) != '0'); i++) {
                val = val * 10 + (num.charAt(i) - '0');
                sb.append(num.charAt(i));
                if (index == 0) {
                    dfs(sb, val, val, i + 1);
                    continue;
                }
                sb.setCharAt(sign, '+');
                dfs(sb, sum + val, val, i + 1);
                sb.setCharAt(sign, '-');
                dfs(sb, sum - val, -val, i + 1);
                sb.setCharAt(sign, '*');
                dfs(sb, sum - prepareMultiply + prepareMultiply * val, prepareMultiply * val, i + 1);
            }
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        s.num = "123";
        s.target = 6;
        System.out.println(s.addOperators(s.num, s.target));
        s.num = "232";
        s.target = 8;
        System.out.println(s.addOperators(s.num, s.target));
        s.num = "105";
        s.target = 5;
        System.out.println(s.addOperators(s.num, s.target));
    }
}

输出:

[1+2+3, 1*2*3]
[2+3*2, 2*3+2]
[1*0+5, 10-5]

代码2:

import java.util.*;
public class addOperators {
    public static class Solution {
        int n;
        String num;
        List<String> ans;
        int target;
        public List<String> addOperators(String num, int target) {
            List<String> res = new ArrayList<>();
            if (num == null || num.length() == 0) {
                return res;
            }
            dfs(num, target, "", 0, 0, 0, res);
            return res;
        }
        private void dfs(String num, int target, String path, int pos, long eval, long multed, List<String> res) {
            if (pos == num.length()) {
                if (eval == target) {
                    res.add(path);
                }
                return;
            }
            for (int i = pos; i < num.length(); i++) {
                if (i != pos && num.charAt(pos) == '0') {
                    break;
                }
                long cur = Long.parseLong(num.substring(pos, i + 1));
                if (pos == 0) {
                    dfs(num, target, path + cur, i + 1, cur, cur, res);
                } else {
                    dfs(num, target, path + "+" + cur, i + 1, eval + cur, cur, res);
                    dfs(num, target, path + "-" + cur, i + 1, eval - cur, -cur, res);
                    dfs(num, target, path + "*" + cur, i + 1, eval - multed + multed * cur, multed * cur, res);
                }
            }
        }
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        System.out.println(s.addOperators("123", 6));
        System.out.println(s.addOperators("232", 8));
        System.out.println(s.addOperators("105", 5));
    }
}

🌟 每日一练刷题专栏 🌟

 持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

 评论,你的意见是我进步的财富!  

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏