文章目录
- 题目:最大重复子字符串
- 题解
- 题目: 面试题 16.07. 最大数值
- 题解
- 题目: 最大字符串配对数目
- 题解
- 题目: 字符串中第二大的数字
- 题解
- 题目: 统计最大组的数目
- 题解
- 题目: 删除每行中的最大值
- 题解
- 题目: 二叉树的所有路径
- 题解
- 题目: 七进制数
- 题解
- 题目: N 叉树的最大深度
- 题解
- 题目: 反转字符串中的单词 III
- 题解
- 题目: 员工奖金 -- sql
- 题解
- 题目: N 叉树的前序遍历
- 题解
- 题目: N 叉树的后序遍历
- 题解
- 题目: N 叉树的层序遍历
- 题解
- 题目: 最长和谐子序列
- 题解
- 题目: 种花问题
- 题解
- 题目: 三个数的最大乘积
- 题解
- 题目: 二叉树中第二小的节点
- 题解
- 总结
题目:最大重复子字符串
原题链接:最大重复子字符串
题解
方法:暴力延长word的重复次数并比较
,用contains()函数
public static int maxRepeating(String sequence, String word) {
int maxRepeat = 0;
StringBuilder repeatedWord = new StringBuilder(word);
// 循环尝试增加word的重复次数,直到不再是子字符串
while (sequence.contains(repeatedWord)) {
maxRepeat++;
repeatedWord.append(word);
}
return maxRepeat;
}
题目: 面试题 16.07. 最大数值
原题链接: 面试题 16.07. 最大数值
题解
方法:通过计算两个整数差值的符号位
表达式 a * (1 - sign) + b * sign
能够实现两个值的二选一效果
public int maximum(int a, int b) {
long diff = (long)a - (long)b;
long sign = (diff >>> 63) & 1;
return (int)(a * (1 - sign) + b * sign);
}
题目: 最大字符串配对数目
原题链接: 最大字符串配对数目
题解
public static int maximumNumberOfStringPairs(String[] words) {
HashSet<String> set = new HashSet<>();
int count = 0;
for (String word : words) {
String reversed = "" + word.charAt(1) + word.charAt(0);
// 检查反转字符串是否已经存在于 set 中
if (set.contains(reversed)) {
count++;
}
set.add(word);
}
return count;
}
题目: 字符串中第二大的数字
原题链接: 字符串中第二大的数字
题解
方法1:
public static int secondHighest(String s) {
Set<Integer> set = new HashSet<>();
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
set.add(c - '0');
}
}
int firstMax = -1;
int secondMax = -1;
for (Integer i : set) {
if (i > firstMax) {
secondMax = firstMax;
firstMax = i;
} else if (i > secondMax && i < firstMax) {
secondMax = i;
}
}
return secondMax;
}
方法2:
先找到最大值删除,如果set不为空,继续寻找最大值(答案)
public static int secondHighest11(String s) {
Set<Integer> set = new HashSet<>();
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
set.add(c - '0');
}
}
int maxValue = -1;
for (Integer i : set) {
if (i > maxValue) {
maxValue = i;
}
}
set.remove(maxValue);
if (set.size() == 0) return -1;
maxValue = -1;
for (Integer i : set) {
if (i > maxValue) {
maxValue = i;
}
}
return maxValue;
}
题目: 统计最大组的数目
原题链接: 统计最大组的数目
题解
方法:利用 map 将相同的数位和作为键
(哈希表
)
public static int sumDigit(int i) {
int res = 0;
while (i > 0) {
res += i % 10;
i /= 10;
}
return res;
}
public static int countLargestGroup(int n) {
int maxCnt = 0;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 1; i <= n; i++) {
int sum = sumDigit(i);
int count = map.getOrDefault(sum, 0) + 1;
map.put(sum, count);
maxCnt = Math.max(maxCnt, count);
}
int res = 0;
for (Integer value : map.values()) {
if (value == maxCnt) {
res++;
}
}
return res;
}
题目: 删除每行中的最大值
原题链接: 删除每行中的最大值
题解
方法:通过逐列查找每一行未使用的最大值,并将其标记为已使用,然后将每列的最大值累加得到最终结果。主要利用 used 数组来跟踪已经处理过的元素
。
public boolean[][] used = new boolean[51][51];
// 找到一行中最最大的元素 并标记已处理
public int findMaxByRow(int[][] grid, int row) {
int maxValue = -1;
int maxIndex = -1;
for (int i = 0; i < grid[0].length; i++) {
if (!used[row][i] && grid[row][i] > maxValue) {
maxValue = grid[row][i];
maxIndex = i;
}
}
if (maxIndex != -1) {
used[row][maxIndex] = true;
}
return maxValue;
}
public int deleteGreatestValue(int[][] grid) {
int res = 0;
for (int j = 0; j < grid[0].length; j++) {
int maxValue = -1;
for (int i = 0; i < grid.length; i++) {
int maxByRow = findMaxByRow(grid, i);
if (maxValue < maxByRow)
maxValue = maxByRow;
}
res += maxValue;
}
return res;
}
题目: 二叉树的所有路径
原题链接: 二叉树的所有路径
题解
方法:创建两个队列,一个用于存储当前节点 (nodeQueue),另一个用于存储从根节点到当前节点的路径 (pathQueue)。将根节点和路径 “root.val” 入队。
先去看一下二叉树层次遍历,然后看这个题,就很简单了
public List<String> binaryTreePaths(TreeNode root) {
List<String> paths = new ArrayList<String>();
if (root == null) {
return paths;
}
Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
Queue<String> pathQueue = new LinkedList<String>();
nodeQueue.offer(root);
pathQueue.offer(Integer.toString(root.val));
while (!nodeQueue.isEmpty()) {
TreeNode node = nodeQueue.poll();
String path = pathQueue.poll();
if (node.left == null && node.right == null) {
paths.add(path);
} else {
if (node.left != null) {
nodeQueue.offer(node.left);
pathQueue.offer(new StringBuffer(path).append("->").append(node.left.val).toString());
}
if (node.right != null) {
nodeQueue.offer(node.right);
pathQueue.offer(new StringBuffer(path).append("->").append(node.right.val).toString());
}
}
}
return paths;
}
题目: 七进制数
原题链接: 七进制数
题解
方法:除7取于法
,余数倒着写
public static String convertToBase7(int num) {
if (num == 0) return "0";
StringBuilder res = new StringBuilder();
int flag = num < 0 ? -1 : 1;
num = Math.abs(num);
while (num > 0) {
res.append(num % 7);
num /= 7;
}
return flag == 1 ? res.reverse().toString() : "-" + res.reverse().toString();
}
题目: N 叉树的最大深度
原题链接: N 叉树的最大深度
题解
方法1:广度优先搜索
在每次进入 while 循环时,首先获取 queue 中的节点数量,这代表当前层的节点数
。接着,逐一处理这些节点,将它们的子节点添加到 queue 中
public int maxDepth(Node root) {
if (root == null) return 0;
int res = 0;
LinkedList<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
res += 1;
int size = queue.size();
while (size > 0) {
Node node = queue.poll();
queue.addAll(node.children);
size--;
}
}
return res;
}
方法2: 深度优先搜索
public int maxDepth(Node root) {
if (root == null) return 0;
int maxDepth = 0;
List<Node> children = root.children;
for (Node child : children) {
int childDepth = maxDepth(child);
maxDepth = Math.max(maxDepth, childDepth);
}
return maxDepth+1;
}
题目: 反转字符串中的单词 III
原题链接: 反转字符串中的单词 III
题解
方法:主要通过 StringBuilder 的 reverse() 方法来反转每个单词
public String reverseWords(String s) {
String[] words = s.split(" ");
StringBuilder res = new StringBuilder();
for (String word : words) {
res.append(new StringBuilder(word).reverse()).append(" ");
}
return res.toString().trim();
}
题目: 员工奖金 – sql
原题链接: 员工奖金
题解
方法:因为奖金为空的也要用null表示。因为加一个:or b.bonus is null
select e.name,b.bonus
from Employee as e left join Bonus as b on e.empId=b.empId
where b.bonus < 1000 or b.bonus is null;
题目: N 叉树的前序遍历
原题链接: N 叉树的前序遍历
题解
方法:N 叉树的前序遍历与二叉树的前序遍历的思路和方法基本一致
前序遍历:根左右
public List<Integer> preorder(Node root) {
List<Integer> res = new ArrayList<>();
helper(root, res);
return res;
}
public void helper(Node root, List<Integer> res) {
if (root == null) return;
res.add(root.val); // 访问根元素
for (Node child : root.children) {
helper(child, res);
}
}
二叉树前序遍历:
List<Integer> res = new ArrayList<>();
// 前序遍历
public List<Integer> preorderTraversal(TreeNode root) {
if (root == null) return res;
res.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return res;
}
题目: N 叉树的后序遍历
原题链接: N 叉树的后序遍历
题解
public List<Integer> postorder(Node root) {
List<Integer> res = new ArrayList<>();
helper(root, res);
return res;
}
private void helper(Node root, List<Integer> res) {
if (root == null) return;
for (Node child : root.children) {
helper(child, res);
}
res.add(root.val);
}
题目: N 叉树的层序遍历
原题链接: N 叉树的层序遍历
题解
方法:和二叉树层次遍历相同,借助队列queue
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
LinkedList<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList<Integer> list = new ArrayList<>();
while (size > 0) {
Node node = queue.poll();
list.add(node.val);
for (Node child : node.children) {
queue.offer(child);
}
size--;
}
res.add(list);
}
return res;
}
题目: 最长和谐子序列
原题链接: 最长和谐子序列
题解
方法:这个方法利用 HashMap 记录每个数字的出现次数,并通过检查每个数字和它的下一个数字是否同时存在来寻找和谐子数组的最大长度。
public static int findLHS(int[] nums) {
int res = 0;
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, (1 + map.getOrDefault(num, 0)));
}
for (Integer i : map.keySet()) {
if (map.containsKey(i + 1)) {
res = Math.max(res, map.get(i) + map.get(i + 1));
}
}
return res;
}
题目: 种花问题
原题链接: 种花问题
题解
方法:通过遍历花坛,检查每个位置是否可以放置花朵,确保前后位置均为空
。它在合适的位置放置花朵,并计算可以放置的总花朵数,最终判断是否能满足所需的花朵数量。
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int count = 0;
for (int i = 0; i < flowerbed.length; i++) {
// 如果当前位置是 0 且前后位置也为空(边界条件也要考虑)
if (flowerbed[i] == 0 &&
(i == 0 || flowerbed[i - 1] == 0) &&
(i == flowerbed.length - 1 || flowerbed[i + 1] == 0)) {
// 放置花朵
flowerbed[i] = 1;
count++;
}
}
return count >= n;
}
题目: 三个数的最大乘积
原题链接: 三个数的最大乘积
题解
方法:排序
我第一想法没考虑到排序,感觉刷迷糊了😭
public int maximumProduct(int[] nums) {
Arrays.sort(nums);
return Math.max(nums[0] * nums[1] * nums[nums.length - 1], nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]);
}
题目: 二叉树中第二小的节点
原题链接: 二叉树中第二小的节点
题解
方法1:
public static int findSecondMinimumValue(TreeNode root) {
HashSet<Integer> set = new HashSet<>();
helper(root, set);
if (set.size() < 2) return -1;
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
for (int i : set) {
if (i < min1) {
min1 = i;
}
}
set.remove(min1);
for (int i : set) {
if (i < min2) {
min2 = i;
}
}
return min2;
}
public static void helper(TreeNode root, HashSet<Integer> set) {
if (root == null) return;
set.add(root.val);
helper(root.left, set);
helper(root.right, set);
}
方法:
public static int findSecondMinimumValue(TreeNode root) {
if (root == null) return -1;
// 初始最小值为根节点的值
int firstMin = root.val;
// 使用递归找出第二小的值
return findSecondMinimum(root, firstMin);
}
private static int findSecondMinimum(TreeNode root, int firstMin) {
if (root == null) return -1;
// 如果当前节点值大于最小值,可能是第二小的值
if (root.val > firstMin) return root.val;
// 递归查找左右子树中的第二小值
int left = findSecondMinimum(root.left, firstMin);
int right = findSecondMinimum(root.right, firstMin);
// 处理左右子树的值
if (left != -1 && right != -1) {
return Math.min(left, right);
}
return Math.max(left, right);
}
总结
- 拿到一个题目要
认真读题
(建议读2遍),没思路可以看一下提示,有时候提示会给你一些解题思路的 - 不要被给的输入输出示例迷惑了,有时候会干扰你解题的