题目描述:
给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
解题思路:
能组成三角形,三边需要满足:① 任意2边的和,大于第三边
② 任意2边的差的绝对值小于第三边
测试数据:
输入:
1 3 5 6 7 9 12
输出:12
解法一(遍历的方式实现):
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static List<List<Integer>> result = new ArrayList<>();
public static List<Integer> path = new ArrayList<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line = in.nextLine();
String[] arrStr = line.split(" ");
int[] nums = new int[arrStr.length];
for (int i = 0; i < arrStr.length; i++) {
nums[i] = Integer.valueOf(arrStr[i]);
}
List<List<Integer>> res = combine(nums);
System.out.println(res);
System.out.println(res.size());
in.close();
}
public static List<List<Integer>> combine(int[] nums) {
for (int i = 0; i < nums.length; i++) {
path.add(nums[i]);
for (int j = i + 1; j < nums.length; j++) {
path.add(nums[j]);
for (int k = j + 1; k < nums.length; k++) {
path.add(nums[k]);
Integer v1 = path.get(0);
Integer v2 = path.get(1);
Integer v3 = path.get(2);
if (v1 + v2 > v3 && Math.abs(v1 - v2) < v3) {
result.add(new ArrayList<>(path));
}
path.remove(path.size() - 1);
}
path.remove(path.size() - 1);
}
path.clear();
}
return result;
}
}
解法二(回溯算法实现):
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static List<List<Integer>> result = new ArrayList<>();
public static List<Integer> path = new ArrayList<>();
public static Map<String, Boolean> setMap = new HashMap<>();
// 给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line = in.nextLine();
String[] arrStr = line.split(" ");
int[] nums = new int[arrStr.length];
for (int i = 0; i < arrStr.length; i++) {
nums[i] = Integer.valueOf(arrStr[i]);
}
List<List<Integer>> res = combine(nums, 3);
System.out.println(res);
System.out.println(res.size());
in.close();
}
public static List<List<Integer>> combine(int[] nums, int k) {
result.clear();
path.clear();
backtracking(nums, k, 0);
return result;
}
public static void backtracking(int[] nums, int k, int startIndex) {
if (path.size() == k) {
ArrayList<Integer> sort = new ArrayList<>(path);
sort.sort((o1, o2) -> o1.intValue() - o2);
Integer v1 = sort.get(0);
Integer v2 = sort.get(1);
Integer v3 = sort.get(2);
if (v1.intValue() != v2 && v2.intValue() != v3 && v1.intValue() != v3
&& v1 + v2 > v3 && Math.abs(v1 - v2) < v3) {
String mapKey = v1 + "-" + v2 + "-" + v3;
if(!setMap.containsKey(mapKey)) {
result.add(new ArrayList<>(path));
setMap.put(mapKey, true);
}
}
return;
}
for (int i = startIndex; i < nums.length; i++) {
path.add(nums[i]);
backtracking(nums, k, startIndex + 1);
if(startIndex == 0) {
path.clear();
} else {
path.remove(path.size() - 1);
}
}
}
}
测试验证结果:
解法一的截图:
解法二的截图: