leetcode-611 有效三角形的个数 [Java]

题目:

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();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值