题目:
611. 有效三角形的个数https://leetcode-cn.com/problems/valid-triangle-number/
一:暴力 三重循环
值得思考的是,如果首先排序的话,有a<b<c,那么a+c>b和b+c>a必定成立,只需判断a+b>c是否成立即可。
代码:
class Solution {
public int triangleNumber(int[] nums) {
int n=nums.length;
int ans=0;
Arrays.sort(nums);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
// 三层循环
for(int k=j+1;k<n;k++){
if(nums[i]+nums[j]>nums[k]){
ans++;
}
}
}
}
return ans;
}
}
结果:
法二:考虑到暴力时间复杂度过高,在第三层换用二分查找寻找分界点。
class Solution {
public int triangleNumber(int[] nums) {
int n=nums.length;
int ans=0;
Arrays.sort(nums);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
// 第三层 优化:二分查找
int low=j+1;
int high=n-1;
int k=j;//保存第三层分界点
while(low<=high){
int mid=(low+high)/2;
if(nums[i]+nums[j]>nums[mid]){
k=mid;
low=mid+1;
}else{
high=mid-1;
}
}
ans+=k-j;//即k-(j+1)+1
}
}
return ans;
}
结果:
升级一下这道题目:(不是力扣里的题目了)
想法:在上一题的基础上,每次找到三角形时,将数字拼接为字符串,使用hashset的特性存储唯一字符串。
代码:
class Solution {
public int triangleNumber(int[] nums) {
int n=nums.length;
//借助hashset存唯一key
HashSet<String> set = new HashSet<>();
int ans=0;
Arrays.sort(nums);
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
// 暴力:三层循环
for(int k=j+1;k<n;k++){//三层循环再优化一下
if(nums[i]+nums[j]>nums[k]){
String s=nums[i]+""+nums[j]+""+nums[k];
set.add(s);
}
}
// 第三层 优化:二分查找
int low=j+1;
int high=n-1;
int k=j; //保存第三层分界点
while(low<=high){
int mid=(low+high)/2;
if(nums[i]+nums[j]>nums[mid]){
k=mid;
low=mid+1;
}else{
high=mid-1;
}
}
for(int a=j+1;a<=k;a++){
String s=nums[i]+""+nums[j]+""+nums[a];
set.add(s);
}
}
}
// 调试时可视化结果
// set.stream().forEach(System.out::println);
return set.size();
}
}