611. 有效三角形的个数(双指针)

611. 有效三角形的个数

方法一、暴力

时间复杂度O(n^3)

class Solution {
    public int triangleNumber(int[] nums) {
    	int n = nums.length;
    	int res = 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]) {
						break;
					}
					res ++ ;
				}
			}
		}
    	return res;
    }
}
方法二、折半查找

时间复杂度O(n2logn)

class Solution {
	public int triangleNumber(int[] nums) {
		int n = nums.length;
		int res = 0;
		Arrays.sort(nums);
		for (int i = 0; i < n - 2; i++) {
			for (int j = i + 1; j < n - 1; j++) {
				int left = j + 1, right = n - 1;
				int mid = left + (right - left) / 2;
				while (left <= right) {
					mid = left + (right - left) / 2;
					if (nums[i] + nums[j] > nums[mid]) {
						left = mid + 1;
					}else {
						right = mid - 1;
					}
				}
				res += right - j;
			}
		}
		return res;
	}
}

下面一种方法学习一下,没能想到。

方法三、双指针

数组排序O(nlogn)是省不了的,前面的方法固定了短的两条边,本方法固定了长边,对其他两条边使用双指针扫描,两条短边的指针分别为left,right,长边的指针i

  • 如果nums[left] + nums[right] > nums[i] ,那么left右边的都能组成三角形,有 j - i 种,下一步将right指针右移。

  • 如果nums[left] + nums[right] <= nums[i],那么将left指针向右移,继续检查

因为左右指针每次都有一个不同,所以不会有重复的。

对于每一条长边,进行一次双指针扫描,而一次双指针扫描时间复杂度为O(n),总的时间复杂度为O(n^2),双指针666

class Solution {
	public int triangleNumber(int[] nums) {
		int n = nums.length;
		int res = 0;
		Arrays.sort(nums);
		for (int i = n - 1; i >= 2; i--) {
			int left = 0, right = i - 1;
			while(left < right) {
				if(nums[left] + nums[right] > nums[i]) {
					res += right - left;
					right -- ;
				}else {
					left++;
				}
			}
		}
		return res;
	}
}

你可能感兴趣的:(LeetCode,算法,指针,数据结构,leetcode,算法)