小红拿到了一个数组,她希望取其中的三个数,使得以这三个数为边长的三角形周长尽可能小。你能帮帮她吗?
数据范围
,
注意:输入数据中保证至少能形成一个三角形
import java.util.*; /** * NC414 小红的最小三角形周长 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 相似 -> NC254 合法的三角形个数 [nowcoder] * * @param nums int整型ArrayList * @return int整型 */ public int hongstriangle (ArrayList<Integer> nums) { // return solution1(nums); return solution2(nums); // return solution3(nums); } /** * 双指针+二分 * @param nums * @return */ private int solution1(ArrayList<Integer> nums){ Collections.sort(nums); int n = nums.size(); long result = Long.MAX_VALUE; long target; int left,right,mid,cnt; long sum; // 三角形两边之和大于第三边 for(int i=0; i<n; i++){ for(int j=i+1; j<n-1; j++){ // 当前最小的三边之和(可能不合法) sum = (long) nums.get(i)+nums.get(j)+nums.get(j+1); if(sum >= result){ break; } // 两条短边之和 target = (long) nums.get(i)+nums.get(j); // 二分 left = j+1; right = n-1; while(left <= right){ mid = (left+right)/2; if(nums.get(mid) < target){ left = mid+1; }else{ right = mid-1; } } // 可选第三边个数 cnt = (left-j-1); if(cnt > 0){ result = sum; } } } return (int)result; } /** * 双指针: 简化 * @param nums * @return */ private int solution2(ArrayList<Integer> nums){ Collections.sort(nums); int n = nums.size(); long result = Long.MAX_VALUE; long target; long sum; // 三角形两边之和大于第三边 for(int i=0; i<n; i++){ // 较大两边索引一定相邻(连续)! for(int j=i+1; j<n-1; j++){ // 当前最小的三边之和(可能不合法) sum = (long) nums.get(i)+nums.get(j)+nums.get(j+1); if(sum >= result){ break; } // 两条短边之和 target = (long) nums.get(i)+nums.get(j); if(target > nums.get(j+1)){ result = sum; break; } } } return (int)result; } /** * 二分 * @param nums * @return */ private int solution3(ArrayList<Integer> nums){ Collections.sort(nums); int n = nums.size(); int result = Integer.MAX_VALUE; int target; int left,right,mid; // 较大两边索引一定相邻(连续)! for(int i=2; i<n; i++){ // A+B>C => A>C-B 第三条最小边大于target target = nums.get(i)-nums.get(i-1); left = 0; right = i-2; while(left <= right){ mid = left+(right-left)/2; // left最终指向第一个大于target的位置 if(nums.get(mid) <= target){ left = mid+1; }else{ right = mid-1; } } if(left <= i-2){ result = Math.min(result, nums.get(left)+nums.get(i)+nums.get(i-1)); } } return result; } }
/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @param numsLen int nums数组长度 * @return int整型 */ int cnp(const void* a,const void *b) { return *(int *)a-*(int *)b; } int hongstriangle(int* nums, int numsLen ) { // write code here qsort(nums,numsLen,sizeof(int),cnp); int left; int mid; int right; //int max=0; if(numsLen<3) return -1; else{ for(right=2;right<numsLen;right++){ for(left=0;left<right-1;left++){ for(mid=left+1;mid<right;mid++){ if(nums[left]+nums[mid]>nums[right]) return nums[left]+nums[mid]+nums[right]; } } } } return -1; }