10.10 华为题
This commit is contained in:
parent
425feff3c7
commit
3d5587b297
85
src/main/java/All/DeckRevealedIncreasing.java
Normal file
85
src/main/java/All/DeckRevealedIncreasing.java
Normal file
@ -0,0 +1,85 @@
|
||||
package All;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* 题目: 950. 按递增顺序显示卡牌
|
||||
* 描述:牌组中的每张卡牌都对应有一个唯一的整数。你可以按你想要的顺序对这套卡片进行排序。
|
||||
* 最初,这些卡牌在牌组里是正面朝下的(即,未显示状态)。
|
||||
* 现在,重复执行以下步骤,直到显示所有卡牌为止:
|
||||
* 从牌组顶部抽一张牌,显示它,然后将其从牌组中移出。
|
||||
* 如果牌组中仍有牌,则将下一张处于牌组顶部的牌放在牌组的底部。
|
||||
* 如果仍有未显示的牌,那么返回步骤 1。否则,停止行动。
|
||||
* 返回能以递增顺序显示卡牌的牌组顺序。
|
||||
* 答案中的第一张牌被认为处于牌堆顶部。
|
||||
|
||||
示例 1:
|
||||
输入:[17,13,11,2,3,5,7]
|
||||
输出:[2,13,3,11,5,17,7]
|
||||
解释:
|
||||
我们得到的牌组顺序为 [17,13,11,2,3,5,7](这个顺序不重要),然后将其重新排序。
|
||||
重新排序后,牌组以 [2,13,3,11,5,17,7] 开始,其中 2 位于牌组的顶部。
|
||||
我们显示 2,然后将 13 移到底部。牌组现在是 [3,11,5,17,7,13]。
|
||||
我们显示 3,并将 11 移到底部。牌组现在是 [5,17,7,13,11]。
|
||||
我们显示 5,然后将 17 移到底部。牌组现在是 [7,13,11,17]。
|
||||
我们显示 7,并将 13 移到底部。牌组现在是 [11,17,13]。
|
||||
我们显示 11,然后将 17 移到底部。牌组现在是 [13,17]。
|
||||
我们展示 13,然后将 17 移到底部。牌组现在是 [17]。
|
||||
我们显示 17。
|
||||
由于所有卡片都是按递增顺序排列显示的,所以答案是正确的。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/reveal-cards-in-increasing-order/
|
||||
*/
|
||||
//不会
|
||||
public class DeckRevealedIncreasing {
|
||||
/**
|
||||
* 希望显示出来的牌是: [2, 3, 5, 7, 11, 13, 17]
|
||||
* 要求反推出原始牌堆的顺序。
|
||||
* 原始牌堆 [2,13,3,11,5,17,7]
|
||||
* 显示顺序 [2,3,5,7,11,13,17]
|
||||
*
|
||||
* 核心思路:逆推法(Reverse Simulation)
|
||||
* 我们从结果往回推(反向模拟):
|
||||
* 显示顺序是 [2,3,5,7,11,13,17](升序),
|
||||
* 那么:
|
||||
* 最后显示的牌是 17,说明它最初在最底;
|
||||
* 在它之前显示的是 13,说明在那时:
|
||||
* 把 17 移到牌堆顶;
|
||||
* 然后把 13 放到牌堆顶;
|
||||
* 依次反推即可。
|
||||
*/
|
||||
public int[] deckRevealedIncreasing(int[] deck) {
|
||||
Arrays.sort(deck); // 升序排列:我们希望显示顺序是递增的
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
|
||||
// 从最后一张牌开始反向构建队列
|
||||
for (int i = deck.length - 1; i >= 0; i--) {
|
||||
if (!deque.isEmpty()) {
|
||||
// 1️⃣ 将队尾的牌移动到队首(模拟“倒回去”的操作)
|
||||
Integer last = deque.pollLast(); // 安全取出队尾(为空时返回 null)
|
||||
deque.offerFirst(last); // 插入到队首
|
||||
}
|
||||
|
||||
// 2️⃣ 把当前牌放到队首
|
||||
deque.offerFirst(deck[i]);
|
||||
}
|
||||
|
||||
// 3️⃣ 把双端队列转成数组输出
|
||||
int[] res = new int[deck.length];
|
||||
int idx = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
res[idx++] = deque.pollFirst(); // 从队首依次取出
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DeckRevealedIncreasing solution = new DeckRevealedIncreasing();
|
||||
int[] deck = {17,13,11,2,3,5,7};
|
||||
System.out.println(Arrays.toString(solution.deckRevealedIncreasing(deck)));
|
||||
// 输出: [2, 13, 3, 11, 5, 17, 7]
|
||||
}
|
||||
}
|
||||
63
src/main/java/All/Multiply.java
Normal file
63
src/main/java/All/Multiply.java
Normal file
@ -0,0 +1,63 @@
|
||||
package All;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 题目: 43. 字符串相乘
|
||||
* 描述:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
|
||||
* 注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
|
||||
|
||||
示例 1:
|
||||
输入: num1 = "2", num2 = "3"
|
||||
输出: "6"
|
||||
|
||||
* 链接:https://leetcode.cn/problems/multiply-strings/
|
||||
*/
|
||||
//不断调试出来了
|
||||
public class Multiply {
|
||||
public String multiply(String num1, String num2) {
|
||||
if (num1.equals("0") || num2.equals("0")) return "0";
|
||||
|
||||
int len1 = num1.length(), len2 = num2.length();
|
||||
int[] temp = new int[len1 + len2 + 1];
|
||||
Arrays.fill(temp, -1);
|
||||
|
||||
// 累加各位乘积
|
||||
for (int i = len1 - 1; i >= 0; i--) {
|
||||
int start = len1 - i - 1;
|
||||
int a = num1.charAt(i) - '0';
|
||||
for (int j = len2 - 1; j >= 0; j--) {
|
||||
int b = num2.charAt(j) - '0';
|
||||
if (temp[start] == -1) temp[start] = 0;
|
||||
temp[start] += a * b;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
// 进位归一化
|
||||
int carry = 0, used = 0;
|
||||
for (; used < temp.length; used++) {
|
||||
if (temp[used] == -1) break;
|
||||
int cur = temp[used] + carry;
|
||||
temp[used] = cur % 10;
|
||||
carry = cur / 10;
|
||||
}
|
||||
while (carry > 0) {
|
||||
temp[used++] = carry % 10;
|
||||
carry /= 10;
|
||||
}
|
||||
|
||||
// 构造结果(从低位到高位拼接后反转)
|
||||
StringBuilder sb = new StringBuilder(used);
|
||||
for (int i = used - 1; i >= 0; i--) {
|
||||
sb.append(temp[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String num1 = "123", num2 = "456";
|
||||
Multiply multiply = new Multiply();
|
||||
System.out.println(multiply.multiply(num1, num2)); // 56088
|
||||
}
|
||||
}
|
||||
113
src/main/java/All/NumMatchingSubseq.java
Normal file
113
src/main/java/All/NumMatchingSubseq.java
Normal file
@ -0,0 +1,113 @@
|
||||
package All;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 题目: 792. 匹配子序列的单词数
|
||||
* 描述:给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。
|
||||
* 字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。
|
||||
* 例如, “ace” 是 “abcde” 的子序列。
|
||||
*
|
||||
示例 1:
|
||||
输入: s = "abcde", words = ["a","bb","acd","ace"]
|
||||
输出: 3
|
||||
解释: 有三个是 s 的子序列的单词: "a", "acd", "ace"。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/number-of-matching-subsequences/
|
||||
*/
|
||||
//不会
|
||||
public class NumMatchingSubseq {
|
||||
/*
|
||||
预处理 s
|
||||
|
||||
对于 s 中的每个字符,记录它在 s 中所有出现的位置(升序存储)。
|
||||
例如 s = "abcde":
|
||||
'a' -> [0]
|
||||
'b' -> [1]
|
||||
'c' -> [2]
|
||||
'd' -> [3]
|
||||
'e' -> [4]
|
||||
检查一个单词 word 是否为子序列
|
||||
|
||||
用一个变量 prev 记录上一个匹配到的下标(初始为 -1)。
|
||||
对 word 的每个字符 c:
|
||||
在 posMap[c] 的下标列表中,二分查找 第一个 ≥ (prev+1) 的位置。
|
||||
如果找不到,说明 word 不是子序列。
|
||||
如果找到了,更新 prev 为这个下标。
|
||||
如果整个 word 都能找到合适位置,则说明它是子序列。
|
||||
统计结果
|
||||
|
||||
遍历 words,逐个判断是否是子序列,统计个数。
|
||||
|
||||
*/
|
||||
public int numMatchingSubseq(String s, String[] words) {
|
||||
// 预处理 s:对每个字符,记录它在 s 中出现的所有下标(升序)
|
||||
Map<Character, List<Integer>> posMap = new HashMap<>();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
// 如果 posMap 中还没有这个字符,先建一个空列表
|
||||
if (!posMap.containsKey(c)) {
|
||||
posMap.put(c, new ArrayList<>());
|
||||
}
|
||||
// 把当前位置 i 添加进去
|
||||
posMap.get(c).add(i);
|
||||
}
|
||||
|
||||
int count = 0; // 统计有多少个 word 是子序列
|
||||
for (String word : words) {
|
||||
if (isSubsequence(word, posMap)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* lowerBound: 在 list 中二分查找第一个 >= target 的元素下标。
|
||||
* 如果所有元素都 < target,返回 list.size()(表示没找到)。
|
||||
*/
|
||||
private int lowerBound(List<Integer> list, int target) {
|
||||
int left = 0, right = list.size() - 1;
|
||||
while (left <= right) { // 注意这里是 <=
|
||||
int mid = left + (right - left) / 2;
|
||||
if (list.get(mid) < target) {
|
||||
left = mid + 1; // 舍弃左半部分
|
||||
} else {
|
||||
right = mid - 1; // mid 也可能满足条件,缩小右边界
|
||||
}
|
||||
}
|
||||
return left; // 最终 left 就是第一个 >= target 的位置
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 word 是否是 s 的子序列
|
||||
*/
|
||||
private boolean isSubsequence(String word, Map<Character, List<Integer>> posMap) {
|
||||
int prev = -1; // 上一个字符在 s 中匹配到的位置,初始为 -1(表示还没匹配)
|
||||
for (char c : word.toCharArray()) {
|
||||
// 如果 s 中根本没有字符 c,直接返回 false
|
||||
if (!posMap.containsKey(c)) return false;
|
||||
|
||||
// list 保存了 c 在 s 中所有出现位置
|
||||
List<Integer> list = posMap.get(c);
|
||||
|
||||
// 在 list 中找一个 >= prev+1 的位置,保证相对顺序
|
||||
int idx = lowerBound(list, prev + 1);
|
||||
|
||||
// 如果没找到(idx == list.size()),说明 word 不是子序列
|
||||
if (idx == list.size()) return false;
|
||||
|
||||
// 更新 prev,记录当前字符在 s 中匹配到的位置
|
||||
prev = list.get(idx);
|
||||
}
|
||||
return true; // 所有字符都能找到合适位置,说明 word 是子序列
|
||||
}
|
||||
|
||||
// 测试
|
||||
public static void main(String[] args) {
|
||||
NumMatchingSubseq solver = new NumMatchingSubseq();
|
||||
String s = "abcde";
|
||||
String[] words = {"a", "bb", "acd", "ace"};
|
||||
System.out.println(solver.numMatchingSubseq(s, words)); // 输出 3
|
||||
}
|
||||
}
|
||||
@ -14,30 +14,28 @@ package All;
|
||||
* 链接:https://leetcode.cn/problems/solve-the-equation/
|
||||
*/
|
||||
public class SolveEquation {
|
||||
class Solution {
|
||||
public String solveEquation(String s) {
|
||||
int x = 0, num = 0, n = s.length();
|
||||
char[] cs = s.toCharArray();
|
||||
for (int i = 0, op = 1; i < n; ) {
|
||||
if (cs[i] == '+') {
|
||||
op = 1; i++;
|
||||
} else if (cs[i] == '-') {
|
||||
op = -1; i++;
|
||||
} else if (cs[i] == '=') {
|
||||
x *= -1; num *= -1; op = 1; i++;
|
||||
} else {
|
||||
int j = i;
|
||||
//找当前数字/变量的边界 比如 "3x"、"x"、"5"。
|
||||
while (j < n && cs[j] != '+' && cs[j] != '-' && cs[j] != '=') j++;
|
||||
//"3x" → "3" "x" → 前面没数字,这时就走 else 1,表示系数是 1
|
||||
if (cs[j - 1] == 'x') x += (i < j - 1 ? Integer.parseInt(s.substring(i, j - 1)) : 1) * op;
|
||||
public String solveEquation(String s) {
|
||||
int x = 0, num = 0, n = s.length();
|
||||
char[] cs = s.toCharArray();
|
||||
for (int i = 0, op = 1; i < n; ) {
|
||||
if (cs[i] == '+') {
|
||||
op = 1; i++;
|
||||
} else if (cs[i] == '-') {
|
||||
op = -1; i++;
|
||||
} else if (cs[i] == '=') {
|
||||
x *= -1; num *= -1; op = 1; i++;
|
||||
} else {
|
||||
int j = i;
|
||||
//找当前数字/变量的边界 比如 "3x"、"x"、"5"。
|
||||
while (j < n && cs[j] != '+' && cs[j] != '-' && cs[j] != '=') j++;
|
||||
//"3x" → "3" "x" → 前面没数字,这时就走 else 1,表示系数是 1
|
||||
if (cs[j - 1] == 'x') x += (i < j - 1 ? Integer.parseInt(s.substring(i, j - 1)) : 1) * op;
|
||||
//如果不是 x 项,就说明是数字,比如 "5"、"10"
|
||||
else num += Integer.parseInt(s.substring(i, j)) * op;
|
||||
i = j;
|
||||
}
|
||||
else num += Integer.parseInt(s.substring(i, j)) * op;
|
||||
i = j;
|
||||
}
|
||||
if (x == 0) return num == 0 ? "Infinite solutions" : "No solution";
|
||||
else return "x=" + (num / -x);
|
||||
}
|
||||
if (x == 0) return num == 0 ? "Infinite solutions" : "No solution";
|
||||
else return "x=" + (num / -x);
|
||||
}
|
||||
}
|
||||
|
||||
88
src/main/java/All/SolveSudoku.java
Normal file
88
src/main/java/All/SolveSudoku.java
Normal file
@ -0,0 +1,88 @@
|
||||
package All;
|
||||
/**
|
||||
* 题目: 37. 解数独
|
||||
* 描述:编写一个程序,通过填充空格来解决数独问题。
|
||||
* 数独的解法需 遵循如下规则:
|
||||
* 数字 1-9 在每一行只能出现一次。
|
||||
* 数字 1-9 在每一列只能出现一次。
|
||||
* 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
|
||||
* 数独部分空格内已填入了数字,空白格用 '.' 表示。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/sudoku-solver/
|
||||
*/
|
||||
//不会
|
||||
public class SolveSudoku {
|
||||
// 行、列、宫格的标记数组
|
||||
private boolean[][] row = new boolean[9][10];
|
||||
private boolean[][] col = new boolean[9][10];
|
||||
private boolean[][] box = new boolean[9][10];
|
||||
|
||||
public void solveSudoku(char[][] board) {
|
||||
// 初始化标记
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
if (board[i][j] != '.') {
|
||||
int num = board[i][j] - '0';
|
||||
row[i][num] = true;
|
||||
col[j][num] = true;
|
||||
box[(i / 3) * 3 + (j / 3)][num] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
backtrack(board, 0, 0);
|
||||
}
|
||||
|
||||
// 回溯:从 (i,j) 开始填充
|
||||
private boolean backtrack(char[][] board, int i, int j) {
|
||||
// 到达终点
|
||||
if (i == 9) return true;
|
||||
|
||||
// 下一个位置 到了本行的最后一列 (0,8),下一个位置应该跳到 下一行的开头 (1,0);
|
||||
int nextI = j == 8 ? i + 1 : i;
|
||||
int nextJ = j == 8 ? 0 : j + 1;
|
||||
|
||||
if (board[i][j] != '.') {
|
||||
return backtrack(board, nextI, nextJ);
|
||||
}
|
||||
|
||||
// 尝试 1-9
|
||||
for (int num = 1; num <= 9; num++) {
|
||||
int boxIndex = (i / 3) * 3 + (j / 3);
|
||||
if (!row[i][num] && !col[j][num] && !box[boxIndex][num]) {
|
||||
// 放置
|
||||
board[i][j] = (char) (num + '0');
|
||||
row[i][num] = col[j][num] = box[boxIndex][num] = true;
|
||||
|
||||
if (backtrack(board, nextI, nextJ)) return true;
|
||||
|
||||
// 撤销
|
||||
board[i][j] = '.';
|
||||
row[i][num] = col[j][num] = box[boxIndex][num] = false;
|
||||
}
|
||||
}
|
||||
return false; // 无解
|
||||
}
|
||||
|
||||
// 测试
|
||||
public static void main(String[] args) {
|
||||
char[][] board = {
|
||||
{'5','3','.','.','7','.','.','.','.'},
|
||||
{'6','.','.','1','9','5','.','.','.'},
|
||||
{'.','9','8','.','.','.','.','6','.'},
|
||||
{'8','.','.','.','6','.','.','.','3'},
|
||||
{'4','.','.','8','.','3','.','.','1'},
|
||||
{'7','.','.','.','2','.','.','.','6'},
|
||||
{'.','6','.','.','.','.','2','8','.'},
|
||||
{'.','.','.','4','1','9','.','.','5'},
|
||||
{'.','.','.','.','8','.','.','7','9'}
|
||||
};
|
||||
SolveSudoku solver = new SolveSudoku();
|
||||
solver.solveSudoku(board);
|
||||
|
||||
// 打印解后的数独
|
||||
for (char[] row : board) {
|
||||
for (char c : row) System.out.print(c + " ");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/main/java/All/SumOddLengthSubarrays.java
Normal file
67
src/main/java/All/SumOddLengthSubarrays.java
Normal file
@ -0,0 +1,67 @@
|
||||
package All;
|
||||
/**
|
||||
* 题目: 1588. 所有奇数长度子数组的和
|
||||
* 描述:给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。
|
||||
* 子数组 定义为原数组中的一个连续子序列。
|
||||
* 请你返回 arr 中 所有奇数长度子数组的和 。
|
||||
|
||||
示例 1:
|
||||
输入:arr = [1,4,2,5,3]
|
||||
输出:58
|
||||
解释:所有奇数长度子数组和它们的和为:
|
||||
[1] = 1
|
||||
[4] = 4
|
||||
[2] = 2
|
||||
[5] = 5
|
||||
[3] = 3
|
||||
[1,4,2] = 7
|
||||
[4,2,5] = 11
|
||||
[2,5,3] = 10
|
||||
[1,4,2,5,3] = 15
|
||||
我们将所有值求和得到 1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58
|
||||
|
||||
* 链接:https://leetcode.cn/problems/sum-of-all-odd-length-subarrays/
|
||||
*/
|
||||
//不会高效做法
|
||||
public class SumOddLengthSubarrays {
|
||||
/*
|
||||
前缀和数组的作用
|
||||
我们先构造一个前缀和数组 prefix,其中 prefix[i] 表示 arr[0..i-1] 的元素和。
|
||||
那么区间 [l, r] 的子数组和就可以快速得到:
|
||||
sum(l, r) = prefix[r+1] - prefix[l]
|
||||
|
||||
遍历所有奇数长度子数组
|
||||
子数组由 (l, r) 确定,长度为 r - l + 1。
|
||||
我们只关心长度为奇数的情况。
|
||||
遍历所有可能的起点 l,再遍历所有终点 r(保证长度奇数),利用前缀和快速算出区间和,加到答案里。
|
||||
|
||||
*/
|
||||
public int sumOddLengthSubarrays(int[] arr) {
|
||||
int n = arr.length;
|
||||
// 前缀和数组,多开一位,prefix[0] = 0
|
||||
int[] prefix = new int[n + 1];
|
||||
for (int i = 0; i < n; i++) {
|
||||
prefix[i + 1] = prefix[i] + arr[i];
|
||||
}
|
||||
|
||||
int ans = 0;
|
||||
// 枚举所有子数组的起点
|
||||
for (int l = 0; l < n; l++) {
|
||||
// 枚举终点
|
||||
for (int r = l; r < n; r++) {
|
||||
int len = r - l + 1;
|
||||
if (len % 2 == 1) { // 只处理奇数长度
|
||||
// 区间和 = prefix[r+1] - prefix[l]
|
||||
ans += prefix[r + 1] - prefix[l];
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SumOddLengthSubarrays solver = new SumOddLengthSubarrays();
|
||||
int[] arr = {1, 4, 2, 5, 3};
|
||||
System.out.println(solver.sumOddLengthSubarrays(arr)); // 输出 58
|
||||
}
|
||||
}
|
||||
83
src/main/java/All/TriangleNumber.java
Normal file
83
src/main/java/All/TriangleNumber.java
Normal file
@ -0,0 +1,83 @@
|
||||
package All;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 题目: 611. 有效三角形的个数
|
||||
* 描述:给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
|
||||
|
||||
示例 1:
|
||||
输入: nums = [2,2,3,4]
|
||||
输出: 3
|
||||
解释:有效的组合是:
|
||||
2,3,4 (使用第一个 2)
|
||||
2,3,4 (使用第二个 2)
|
||||
2,2,3
|
||||
|
||||
* 链接:https://leetcode.cn/problems/number-of-matching-subsequences/
|
||||
*/
|
||||
public class TriangleNumber {
|
||||
|
||||
//回溯法超时了!!!
|
||||
int count=0;
|
||||
|
||||
void backtrack(int[] nums, int start, List<Integer> path){
|
||||
for (int i = start; i < nums.length; i++) {
|
||||
if(nums[i]==0)continue;
|
||||
if(path.size()==2){
|
||||
int first=path.get(0);
|
||||
int second=path.get(1);
|
||||
if(first+second<=nums[i])
|
||||
break;
|
||||
else {
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
path.add(nums[i]);
|
||||
backtrack(nums,i+1,path);
|
||||
path.remove(path.size()-1);
|
||||
}
|
||||
}
|
||||
public int triangleNumber1(int[] nums) {
|
||||
Arrays.sort(nums);
|
||||
List<Integer>path=new ArrayList<>();
|
||||
backtrack(nums,0,path);
|
||||
return count;
|
||||
}
|
||||
|
||||
//双指针法
|
||||
//高效的关键是固定最大边,而不是最小边、次小边!!!
|
||||
public int triangleNumber(int[] nums) {
|
||||
Arrays.sort(nums);
|
||||
int count = 0;
|
||||
int n = nums.length;
|
||||
|
||||
// 固定最长边 nums[k]
|
||||
for (int k = n - 1; k >= 2; k--) {
|
||||
int i = 0, j = k - 1;
|
||||
while (i < j) {
|
||||
// 如果 nums[i] + nums[j] > nums[k]
|
||||
if (nums[i] + nums[j] > nums[k]) {
|
||||
// 那么 [i, j-1] 都满足条件
|
||||
count += (j - i);
|
||||
j--;
|
||||
} else {
|
||||
// 否则 i 太小,往右移动
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TriangleNumber solution = new TriangleNumber();
|
||||
int[] nums= {2,2,3,4};
|
||||
int res=solution.triangleNumber(nums);
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user