首页 > 试题广场 >

小红的最小三角形周长

[编程题]小红的最小三角形周长
  • 热度指数:1229 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小红拿到了一个数组,她希望取其中的三个数,使得以这三个数为边长的三角形周长尽可能小。你能帮帮她吗?


数据范围 ,
注意:输入数据中保证至少能形成一个三角形

示例1

输入

[2,8,4,11,9]

输出

19
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;
    }
}

发表于 2024-10-18 11:54:09 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @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;

}

发表于 2023-01-08 20:12:33 回复(0)
class Solution:
    def hongstriangle(self , nums: List[int]) -> int:
        # write code here
        len1=len(nums)
        nums=sorted(nums)
        res=0
        i0,j0,k0=len1,len1,len1
        for i in range(len1):
            for j in range(i+1,len1):
                for k in range(j+1,len1):
                    if nums[i]+nums[j]>nums[k] :
                        if res>nums[i]+nums[j]+nums[k] or res==0:
                            res=nums[i]+nums[j]+nums[k] 
                            i0,j0,k0=nums[i],nums[j],nums[j]
                    else:
                        break
                if nums[i]>=j0 and nums[j]>=k0:break
            if nums[i]>=k0:break             
        return res
发表于 2022-09-03 16:22:37 回复(0)
是不是大家都被264886031越界给挡住了,结果居然可以是27151
发表于 2022-06-11 19:43:54 回复(0)