【Leetcode刷题篇】leetcode611 有效三角形的个数

给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数。

示例 1:
输入: [2,2,3,4]
输出: 3
解释:
有效的组合是:
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3

注意:
数组长度不超过1000。
数组里整数的范围为 [0, 1000]。

要注意的:边界的问题。
解题思路:第一种方式便是常见的遍历的方法了。

// 第一种方法
	    public int triangleNumber(int[] nums) {
	    	// 判断数组的长度
	    	if(nums.length<3) {
	    		return 0;
	    	}
	    	// 存储结果
	    	int res = 0;
	    	// 遍历
	    	for(int i=0;i<nums.length-2;i++) {
	    		for(int j=i+1;j<nums.length-1;j++) {
	    			for(int k=j+1;k<nums.length;k++) {
	    				if(nums[i]+nums[j]>nums[k]&&nums[i]+nums[k]>nums[j]&&nums[j]+nums[k]>nums[i]) {
	    					res++;
	    				}
	    			}
	    		}
	    	}
	    	return res;
	    }

时间复杂度为:O(N^3)

第二种方法 :便是先对其排序,那么仅需遍历两边,然后找到满足第三边的那个最大值即可。而找这个最大值可通过二分查找的办法。找到最大值的左边界的值

// 第二种方法 确定前两个值之后,寻找第三个值用二分查找的办法 只需满足一条nums[i]+nums[j]>nums[k]
	    public int triangleNumber_2(int[] nums) {
	    	// 判断
	    	if(nums.length<3) {
	    		return 0;
	    	}
            Arrays.sort(nums);
	    	// 结果存储
	    	int res = 0;
	    	for(int i=0;i<nums.length-2;i++) {
	    		// 从最小开始查找
	    		int k = i+2;
	    		for(int j=i+1;j<nums.length-1&&nums[i]!=0;j++) {
	    			k = binarySearch(nums,k,nums.length-1,nums[i]+nums[j]);
	    			res += (k-j-1);
	    		}
	    	}
	    	
	    	return res;
	    }
	    // 二分查找最小值的索引 查找不满足最小两数相加的最小和 找最小值
	    public int binarySearch(int[] nums,int left,int right,int target) {
	    	// 循环条件
	    	while(left<=right&&right<nums.length) {
                int mid = left + ((right-left)>>1);
	    		if(nums[mid]>=target) {
	    			right = mid-1;
	    		}else {
	    			left = mid+1;
	    		}
	    	}
	    	return left;
	    }
	    

时间复杂度为:O(N^2*logN)

第三种解题思路:直接找

public int triangleNumber_3(int[] nums) {
	    	if(nums.length<3) {
	    		return 0;
	    	}
	    	// 排序
	    	Arrays.sort(nums);
	    	int res = 0;
	    	for(int i=0;i<nums.length-2;i++) {
	    		// 判断 边不能为0
	    		if(nums[i]==0) {
	    			continue;
	    		}
	    		int k = i+2;
	    		for(int j=i+1;j<nums.length-1;j++) {
	    			// 确定两个值,现在找第三个值 找最小值
	    			while(k<nums.length&&nums[i]+nums[j]>nums[k]) {
	    				k++;
	    			}
	    			res += k-j-1;
	    		}
	    	}
	    	return res;
	    }

时间复杂度为:O(N^2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mind_programmonkey

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值