From 55e0b418b1db5e2c04ad0374aae271292c59b38c Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Fri, 26 Sep 2025 07:36:11 +0800 Subject: [PATCH] feat: update solutions to lc problem: No.0611 --- .../0611.Valid Triangle Number/README.md | 141 +++++++---------- .../0611.Valid Triangle Number/README_EN.md | 143 ++++++++---------- .../0611.Valid Triangle Number/Solution.cpp | 10 +- .../0611.Valid Triangle Number/Solution.go | 18 +-- .../0611.Valid Triangle Number/Solution.rs | 28 ++-- .../0611.Valid Triangle Number/Solution.ts | 17 +-- .../0611.Valid Triangle Number/Solution2.java | 21 --- 7 files changed, 156 insertions(+), 222 deletions(-) delete mode 100644 solution/0600-0699/0611.Valid Triangle Number/Solution2.java diff --git a/solution/0600-0699/0611.Valid Triangle Number/README.md b/solution/0600-0699/0611.Valid Triangle Number/README.md index b0a4484b8ecd2..d1e5b0ef74e07 100644 --- a/solution/0600-0699/0611.Valid Triangle Number/README.md +++ b/solution/0600-0699/0611.Valid Triangle Number/README.md @@ -29,7 +29,7 @@ tags:
 输入: nums = [2,2,3,4]
 输出: 3
-解释:有效的组合是: 
+解释:有效的组合是:
 2,3,4 (使用第一个 2)
 2,3,4 (使用第二个 2)
 2,2,3
@@ -58,13 +58,19 @@ tags:
 
 ### 方法一:排序 + 二分查找
 
-一个有效三角形需要满足:**任意两边之和大于第三边**。即:`a + b > c`①, `a + c > b`②, `b + c > a`③。
+一个有效三角形需要满足:**任意两边之和大于第三边**。即:
 
-如果我们将边按从小到大顺序排列,即 `a < b < c`,那么显然 ②③ 成立,我们只需要确保 ① 也成立,就可以形成一个有效三角形。
+$$a + b \gt c \tag{1}$$
 
-我们在 `[0, n - 3]` 范围内枚举 i,在 `[i + 1, n - 2]` 范围内枚举 j,在 `[j + 1, n - 1]` 范围内进行二分查找,找出第一个大于等于 `nums[i] + nums[j]` 的下标 left,那么在 `[j + 1, left - 1]` 范围内的 k 满足条件,将其累加到结果 ans。
+$$a + c \gt b \tag{2}$$
 
-时间复杂度:$O(n^2\log n)$。
+$$b + c \gt a \tag{3}$$
+
+如果我们将边按从小到大顺序排列,即 $a \leq b \leq c$,那么显然 (2)(3) 成立,我们只需要确保 (1) 也成立,就可以形成一个有效三角形。
+
+我们在 $[0, n - 3]$ 范围内枚举 i,在 $[i + 1, n - 2]$ 范围内枚举 j,在 $[j + 1, n - 1]$ 范围内进行二分查找,找出第一个大于等于 $nums[i] + nums[j]$ 的下标 left,那么在 $[j + 1, left - 1]$ 范围内的 k 满足条件,将其累加到结果 $\textit{ans}$。
+
+时间复杂度 $O(n^2\log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组的长度。
 
 
 
@@ -88,20 +94,22 @@ class Solution:
 class Solution {
     public int triangleNumber(int[] nums) {
         Arrays.sort(nums);
-        int n = nums.length;
-        int res = 0;
-        for (int i = n - 1; i >= 2; --i) {
-            int l = 0, r = i - 1;
-            while (l < r) {
-                if (nums[l] + nums[r] > nums[i]) {
-                    res += r - l;
-                    --r;
-                } else {
-                    ++l;
+        int ans = 0;
+        for (int i = 0, n = nums.length; i < n - 2; ++i) {
+            for (int j = i + 1; j < n - 1; ++j) {
+                int left = j + 1, right = n;
+                while (left < right) {
+                    int mid = (left + right) >> 1;
+                    if (nums[mid] >= nums[i] + nums[j]) {
+                        right = mid;
+                    } else {
+                        left = mid + 1;
+                    }
                 }
+                ans += left - j - 1;
             }
         }
-        return res;
+        return ans;
     }
 }
 ```
@@ -112,12 +120,14 @@ class Solution {
 class Solution {
 public:
     int triangleNumber(vector& nums) {
-        sort(nums.begin(), nums.end());
+        ranges::sort(nums);
         int ans = 0, n = nums.size();
         for (int i = 0; i < n - 2; ++i) {
             for (int j = i + 1; j < n - 1; ++j) {
-                int k = lower_bound(nums.begin() + j + 1, nums.end(), nums[i] + nums[j]) - nums.begin() - 1;
-                ans += k - j;
+                int sum = nums[i] + nums[j];
+                auto it = ranges::lower_bound(nums.begin() + j + 1, nums.end(), sum);
+                int k = int(it - nums.begin()) - 1;
+                ans += max(0, k - j);
             }
         }
         return ans;
@@ -130,19 +140,15 @@ public:
 ```go
 func triangleNumber(nums []int) int {
 	sort.Ints(nums)
+	n := len(nums)
 	ans := 0
-	for i, n := 0, len(nums); i < n-2; i++ {
+	for i := 0; i < n-2; i++ {
 		for j := i + 1; j < n-1; j++ {
-			left, right := j+1, n
-			for left < right {
-				mid := (left + right) >> 1
-				if nums[mid] >= nums[i]+nums[j] {
-					right = mid
-				} else {
-					left = mid + 1
-				}
+			sum := nums[i] + nums[j]
+			k := sort.SearchInts(nums[j+1:], sum) + j + 1 - 1
+			if k > j {
+				ans += k - j
 			}
-			ans += left - j - 1
 		}
 	}
 	return ans
@@ -154,17 +160,14 @@ func triangleNumber(nums []int) int {
 ```ts
 function triangleNumber(nums: number[]): number {
     nums.sort((a, b) => a - b);
-    let n = nums.length;
+    const n = nums.length;
     let ans = 0;
-    for (let i = n - 1; i >= 2; i--) {
-        let left = 0,
-            right = i - 1;
-        while (left < right) {
-            if (nums[left] + nums[right] > nums[i]) {
-                ans += right - left;
-                right--;
-            } else {
-                left++;
+    for (let i = 0; i < n - 2; i++) {
+        for (let j = i + 1; j < n - 1; j++) {
+            const sum = nums[i] + nums[j];
+            let k = _.sortedIndex(nums, sum, j + 1) - 1;
+            if (k > j) {
+                ans += k - j;
             }
         }
     }
@@ -179,56 +182,26 @@ impl Solution {
     pub fn triangle_number(mut nums: Vec) -> i32 {
         nums.sort();
         let n = nums.len();
-        let mut res = 0;
-        for i in (2..n).rev() {
-            let mut left = 0;
-            let mut right = i - 1;
-            while left < right {
-                if nums[left] + nums[right] > nums[i] {
-                    res += right - left;
-                    right -= 1;
-                } else {
-                    left += 1;
-                }
-            }
-        }
-        res as i32
-    }
-}
-```
-
-
-
-
-
-
-
-### 方法二
-
-
-
-#### Java
-
-```java
-class Solution {
-    public int triangleNumber(int[] nums) {
-        Arrays.sort(nums);
-        int ans = 0;
-        for (int i = 0, n = nums.length; i < n - 2; ++i) {
-            for (int j = i + 1; j < n - 1; ++j) {
-                int left = j + 1, right = n;
-                while (left < right) {
-                    int mid = (left + right) >> 1;
-                    if (nums[mid] >= nums[i] + nums[j]) {
-                        right = mid;
-                    } else {
+        let mut ans = 0;
+        for i in 0..n.saturating_sub(2) {
+            for j in i + 1..n.saturating_sub(1) {
+                let sum = nums[i] + nums[j];
+                let mut left = j + 1;
+                let mut right = n;
+                while left < right {
+                    let mid = (left + right) / 2;
+                    if nums[mid] < sum {
                         left = mid + 1;
+                    } else {
+                        right = mid;
                     }
                 }
-                ans += left - j - 1;
+                if left > j + 1 {
+                    ans += (left - 1 - j) as i32;
+                }
             }
         }
-        return ans;
+        ans
     }
 }
 ```
diff --git a/solution/0600-0699/0611.Valid Triangle Number/README_EN.md b/solution/0600-0699/0611.Valid Triangle Number/README_EN.md
index 282cd1ec4a45c..71f290a9365b9 100644
--- a/solution/0600-0699/0611.Valid Triangle Number/README_EN.md	
+++ b/solution/0600-0699/0611.Valid Triangle Number/README_EN.md	
@@ -28,7 +28,7 @@ tags:
 
 Input: nums = [2,2,3,4]
 Output: 3
-Explanation: Valid combinations are: 
+Explanation: Valid combinations are:
 2,3,4 (using the first 2)
 2,3,4 (using the second 2)
 2,2,3
@@ -55,7 +55,21 @@ tags:
 
 
 
-### Solution 1
+### Solution 1: Sorting + Binary Search
+
+A valid triangle must satisfy: **the sum of any two sides is greater than the third side**. That is:
+
+$$a + b \gt c \tag{1}$$
+
+$$a + c \gt b \tag{2}$$
+
+$$b + c \gt a \tag{3}$$
+
+If we arrange the sides in ascending order, i.e., $a \leq b \leq c$, then obviously conditions (2) and (3) are satisfied. We only need to ensure that condition (1) is also satisfied to form a valid triangle.
+
+We enumerate $i$ in the range $[0, n - 3]$, enumerate $j$ in the range $[i + 1, n - 2]$, and perform binary search in the range $[j + 1, n - 1]$ to find the first index $left$ that is greater than or equal to $nums[i] + nums[j]$. Then, the values of $k$ in the range $[j + 1, left - 1]$ satisfy the condition, and we add them to the result $\textit{ans}$.
+
+The time complexity is $O(n^2\log n)$, and the space complexity is $O(\log n)$, where $n$ is the length of the array.
 
 
 
@@ -79,20 +93,22 @@ class Solution:
 class Solution {
     public int triangleNumber(int[] nums) {
         Arrays.sort(nums);
-        int n = nums.length;
-        int res = 0;
-        for (int i = n - 1; i >= 2; --i) {
-            int l = 0, r = i - 1;
-            while (l < r) {
-                if (nums[l] + nums[r] > nums[i]) {
-                    res += r - l;
-                    --r;
-                } else {
-                    ++l;
+        int ans = 0;
+        for (int i = 0, n = nums.length; i < n - 2; ++i) {
+            for (int j = i + 1; j < n - 1; ++j) {
+                int left = j + 1, right = n;
+                while (left < right) {
+                    int mid = (left + right) >> 1;
+                    if (nums[mid] >= nums[i] + nums[j]) {
+                        right = mid;
+                    } else {
+                        left = mid + 1;
+                    }
                 }
+                ans += left - j - 1;
             }
         }
-        return res;
+        return ans;
     }
 }
 ```
@@ -103,12 +119,14 @@ class Solution {
 class Solution {
 public:
     int triangleNumber(vector& nums) {
-        sort(nums.begin(), nums.end());
+        ranges::sort(nums);
         int ans = 0, n = nums.size();
         for (int i = 0; i < n - 2; ++i) {
             for (int j = i + 1; j < n - 1; ++j) {
-                int k = lower_bound(nums.begin() + j + 1, nums.end(), nums[i] + nums[j]) - nums.begin() - 1;
-                ans += k - j;
+                int sum = nums[i] + nums[j];
+                auto it = ranges::lower_bound(nums.begin() + j + 1, nums.end(), sum);
+                int k = int(it - nums.begin()) - 1;
+                ans += max(0, k - j);
             }
         }
         return ans;
@@ -121,19 +139,15 @@ public:
 ```go
 func triangleNumber(nums []int) int {
 	sort.Ints(nums)
+	n := len(nums)
 	ans := 0
-	for i, n := 0, len(nums); i < n-2; i++ {
+	for i := 0; i < n-2; i++ {
 		for j := i + 1; j < n-1; j++ {
-			left, right := j+1, n
-			for left < right {
-				mid := (left + right) >> 1
-				if nums[mid] >= nums[i]+nums[j] {
-					right = mid
-				} else {
-					left = mid + 1
-				}
+			sum := nums[i] + nums[j]
+			k := sort.SearchInts(nums[j+1:], sum) + j + 1 - 1
+			if k > j {
+				ans += k - j
 			}
-			ans += left - j - 1
 		}
 	}
 	return ans
@@ -145,17 +159,14 @@ func triangleNumber(nums []int) int {
 ```ts
 function triangleNumber(nums: number[]): number {
     nums.sort((a, b) => a - b);
-    let n = nums.length;
+    const n = nums.length;
     let ans = 0;
-    for (let i = n - 1; i >= 2; i--) {
-        let left = 0,
-            right = i - 1;
-        while (left < right) {
-            if (nums[left] + nums[right] > nums[i]) {
-                ans += right - left;
-                right--;
-            } else {
-                left++;
+    for (let i = 0; i < n - 2; i++) {
+        for (let j = i + 1; j < n - 1; j++) {
+            const sum = nums[i] + nums[j];
+            let k = _.sortedIndex(nums, sum, j + 1) - 1;
+            if (k > j) {
+                ans += k - j;
             }
         }
     }
@@ -170,56 +181,26 @@ impl Solution {
     pub fn triangle_number(mut nums: Vec) -> i32 {
         nums.sort();
         let n = nums.len();
-        let mut res = 0;
-        for i in (2..n).rev() {
-            let mut left = 0;
-            let mut right = i - 1;
-            while left < right {
-                if nums[left] + nums[right] > nums[i] {
-                    res += right - left;
-                    right -= 1;
-                } else {
-                    left += 1;
-                }
-            }
-        }
-        res as i32
-    }
-}
-```
-
-
-
-
-
-
-
-### Solution 2
-
-
-
-#### Java
-
-```java
-class Solution {
-    public int triangleNumber(int[] nums) {
-        Arrays.sort(nums);
-        int ans = 0;
-        for (int i = 0, n = nums.length; i < n - 2; ++i) {
-            for (int j = i + 1; j < n - 1; ++j) {
-                int left = j + 1, right = n;
-                while (left < right) {
-                    int mid = (left + right) >> 1;
-                    if (nums[mid] >= nums[i] + nums[j]) {
-                        right = mid;
-                    } else {
+        let mut ans = 0;
+        for i in 0..n.saturating_sub(2) {
+            for j in i + 1..n.saturating_sub(1) {
+                let sum = nums[i] + nums[j];
+                let mut left = j + 1;
+                let mut right = n;
+                while left < right {
+                    let mid = (left + right) / 2;
+                    if nums[mid] < sum {
                         left = mid + 1;
+                    } else {
+                        right = mid;
                     }
                 }
-                ans += left - j - 1;
+                if left > j + 1 {
+                    ans += (left - 1 - j) as i32;
+                }
             }
         }
-        return ans;
+        ans
     }
 }
 ```
diff --git a/solution/0600-0699/0611.Valid Triangle Number/Solution.cpp b/solution/0600-0699/0611.Valid Triangle Number/Solution.cpp
index 1fbf4a37f0895..781b0cd7f010f 100644
--- a/solution/0600-0699/0611.Valid Triangle Number/Solution.cpp	
+++ b/solution/0600-0699/0611.Valid Triangle Number/Solution.cpp	
@@ -1,14 +1,16 @@
 class Solution {
 public:
     int triangleNumber(vector& nums) {
-        sort(nums.begin(), nums.end());
+        ranges::sort(nums);
         int ans = 0, n = nums.size();
         for (int i = 0; i < n - 2; ++i) {
             for (int j = i + 1; j < n - 1; ++j) {
-                int k = lower_bound(nums.begin() + j + 1, nums.end(), nums[i] + nums[j]) - nums.begin() - 1;
-                ans += k - j;
+                int sum = nums[i] + nums[j];
+                auto it = ranges::lower_bound(nums.begin() + j + 1, nums.end(), sum);
+                int k = int(it - nums.begin()) - 1;
+                ans += max(0, k - j);
             }
         }
         return ans;
     }
-};
\ No newline at end of file
+};
diff --git a/solution/0600-0699/0611.Valid Triangle Number/Solution.go b/solution/0600-0699/0611.Valid Triangle Number/Solution.go
index 8e84d4f8aa7a8..08610a58fdbcb 100644
--- a/solution/0600-0699/0611.Valid Triangle Number/Solution.go	
+++ b/solution/0600-0699/0611.Valid Triangle Number/Solution.go	
@@ -1,19 +1,15 @@
 func triangleNumber(nums []int) int {
 	sort.Ints(nums)
+	n := len(nums)
 	ans := 0
-	for i, n := 0, len(nums); i < n-2; i++ {
+	for i := 0; i < n-2; i++ {
 		for j := i + 1; j < n-1; j++ {
-			left, right := j+1, n
-			for left < right {
-				mid := (left + right) >> 1
-				if nums[mid] >= nums[i]+nums[j] {
-					right = mid
-				} else {
-					left = mid + 1
-				}
+			sum := nums[i] + nums[j]
+			k := sort.SearchInts(nums[j+1:], sum) + j + 1 - 1
+			if k > j {
+				ans += k - j
 			}
-			ans += left - j - 1
 		}
 	}
 	return ans
-}
\ No newline at end of file
+}
diff --git a/solution/0600-0699/0611.Valid Triangle Number/Solution.rs b/solution/0600-0699/0611.Valid Triangle Number/Solution.rs
index e35b77bab6711..7811373f9a465 100644
--- a/solution/0600-0699/0611.Valid Triangle Number/Solution.rs	
+++ b/solution/0600-0699/0611.Valid Triangle Number/Solution.rs	
@@ -2,19 +2,25 @@ impl Solution {
     pub fn triangle_number(mut nums: Vec) -> i32 {
         nums.sort();
         let n = nums.len();
-        let mut res = 0;
-        for i in (2..n).rev() {
-            let mut left = 0;
-            let mut right = i - 1;
-            while left < right {
-                if nums[left] + nums[right] > nums[i] {
-                    res += right - left;
-                    right -= 1;
-                } else {
-                    left += 1;
+        let mut ans = 0;
+        for i in 0..n.saturating_sub(2) {
+            for j in i + 1..n.saturating_sub(1) {
+                let sum = nums[i] + nums[j];
+                let mut left = j + 1;
+                let mut right = n;
+                while left < right {
+                    let mid = (left + right) / 2;
+                    if nums[mid] < sum {
+                        left = mid + 1;
+                    } else {
+                        right = mid;
+                    }
+                }
+                if left > j + 1 {
+                    ans += (left - 1 - j) as i32;
                 }
             }
         }
-        res as i32
+        ans
     }
 }
diff --git a/solution/0600-0699/0611.Valid Triangle Number/Solution.ts b/solution/0600-0699/0611.Valid Triangle Number/Solution.ts
index 522ad0c45d473..c67688099d9e2 100644
--- a/solution/0600-0699/0611.Valid Triangle Number/Solution.ts	
+++ b/solution/0600-0699/0611.Valid Triangle Number/Solution.ts	
@@ -1,16 +1,13 @@
 function triangleNumber(nums: number[]): number {
     nums.sort((a, b) => a - b);
-    let n = nums.length;
+    const n = nums.length;
     let ans = 0;
-    for (let i = n - 1; i >= 2; i--) {
-        let left = 0,
-            right = i - 1;
-        while (left < right) {
-            if (nums[left] + nums[right] > nums[i]) {
-                ans += right - left;
-                right--;
-            } else {
-                left++;
+    for (let i = 0; i < n - 2; i++) {
+        for (let j = i + 1; j < n - 1; j++) {
+            const sum = nums[i] + nums[j];
+            let k = _.sortedIndex(nums, sum, j + 1) - 1;
+            if (k > j) {
+                ans += k - j;
             }
         }
     }
diff --git a/solution/0600-0699/0611.Valid Triangle Number/Solution2.java b/solution/0600-0699/0611.Valid Triangle Number/Solution2.java
deleted file mode 100644
index 13a17cbea293c..0000000000000
--- a/solution/0600-0699/0611.Valid Triangle Number/Solution2.java	
+++ /dev/null
@@ -1,21 +0,0 @@
-class Solution {
-    public int triangleNumber(int[] nums) {
-        Arrays.sort(nums);
-        int ans = 0;
-        for (int i = 0, n = nums.length; i < n - 2; ++i) {
-            for (int j = i + 1; j < n - 1; ++j) {
-                int left = j + 1, right = n;
-                while (left < right) {
-                    int mid = (left + right) >> 1;
-                    if (nums[mid] >= nums[i] + nums[j]) {
-                        right = mid;
-                    } else {
-                        left = mid + 1;
-                    }
-                }
-                ans += left - j - 1;
-            }
-        }
-        return ans;
-    }
-}
\ No newline at end of file