LeetCode 第14~16题

发布于:2025-03-20 ⋅ 阅读:(17) ⋅ 点赞:(0)

目录

LeetCode 第14题:最长公共前缀

LeetCode 第15题:三数之和

LeetCode 第16题:最接近的三数之和

LeetCode 第14题:最长公共前缀

题目描述

编写一个函数来查找字符数组中的最长公共前缀。如果不存在公共前缀,返回字符串“”。

难度:简单

题目链接:14. 最长公共前缀 - 力扣(LeetCode)

示例1:

输入:strs = ["flower","flow","flight"]
输出:"fl"

 示例2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

提示:

  • 1<=strs.length<=200
  • 0<=strs[i].length<=200
  • strs[i]仅由小写英文字母组成

解题思路:逐位比较所有字符串的相同位置的字符。

public class Solution{
    public string LongestCommonPrefix(string[] strs)
    {
        if(strs==null || strs.length==0)  return "";
        //获取最短字符串的长度
        int minLength = strs[0].Length;
        foreach(string str in strs)
             minLength = Math.min(minLength,str.Length);
        //逐位比较
        StringBuilder result = new StringBuilder();
        for(int i=0;i<minLength;i++)
        {
            char currentChar = strs[0][i];
            //对比所有字符串的当前位置
            for(int j=1;j<strs.Length;j++)
            {
                if(strs[j][i]!=currentChar)  return result.ToString();
            }
            result.Append(currentChar);
        }
        return result.ToString();
    }
}

LeetCode 第15题:三数之和

题目描述

给你一个整数数组nums,判断是否存在三元组[nums[i],nums[j],nums[k]]满足i!=j、i!=k且j!=k,同时还满足nums[j]+nums[j]+nums[k]==0。请你返回所有和为0且不重复的三元组。注意:答案中不可以包含重复的三元组。

难度:中等

题目链接:15. 三数之和 - 力扣(LeetCode)

示例1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

 示例2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3<=nums.length<=3000
  • -105<=nums[i]<=105

 解题思路:排序+双指针

  • 考虑到三元组的不重复性,对数组进行排序并去除重复数字。
  • 遍历数组,固定第一个数nums[i]:
  1. 如果nums[i]>0,因为数组已排序,后面不可能有三个数字之和为0
  2. 如果nums[i]和前一个数相同,跳过以避免重复
  • 使用双指针left和right在[i+1,n-1]范围内寻找和为-nums[i]的两个数
  • 根据三数之和与0的关系移动指针,找到答案时注意去重
  • 时间复杂度:O(n^2)、空间复杂度:O(1)(不考虑存储答案的空间)
//提前判断边界条件
public class Solution{
    public IList<IList<int>> ThreeSum(int[] nums)
    {
        List<IList<int>> result = new List<IList<int>>();
        if(nums==null || nums.length<3)  return result;
        Array.Sort(nums);
        int n=nums.Length;
        
        //如果最小的三个数和大于0,或最大的三个数和小于0,直接返回
        if(nums[0]+nums[1]+nums[2]>0  || nums[n-1]+nums[n-2]+nums[n-3]<0)
               return result;
        for(int i=0;i<n-2;i++)
        {
            if(nums[i]>0)  break;
            if(i>0 && nums[i]==nums[i-1])  continue;
            //计算当前数可能的最小和最大三数之和
            int minSum = nums[i]+nums[i+1]+nums[i+2];
            int maxSum = nums[i]+nums[n-2]+nums[n-1];
            if(minSum>0)   break;
            if(maxSum<0)   continue;
            int left = i+1;
            int right = n-1;
            while(left<right)
            {
                int sum=nums[i]+nums[left]+nums[right];
                if(sum==0)
                {
                    result.Add(new List<int> {nums[i],nums[left],nums[right]});
                    while(left<right && nums[left]==nums[left+1]) left++;
                    while(left<right && nums[right]==nums[right-1]) right--;
                    left++;right--;

                }
                else if(sum<0)  left++;
                else  right--;
            }
    
        } 
        return result;
    }
}

LeetCode 第16题:最接近的三数之和

题目描述

给定一个长度为n的整数数组nums和一个目标值target。请你从nums中选出三个整数,使它们的和与target最接近。返回这三个数的和,假定每组输入只存在恰好一个解。

难度:中等

题目链接:16. 最接近的三数之和 - 力扣(LeetCode)

示例1:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2)。

 示例2:
 

输入:nums = [0,0,0], target = 1
输出:0
解释:与 target 最接近的和是 0(0 + 0 + 0 = 0)。

提示:

  • 3<=nums.length<=1000
  • -1000<nums[i]<=1000
  • -104<=target<=104

解题思路:同上(排序+双指针+剪枝)

public class Solution{
    public int ThreeSumClosest(int[] nums,int target)
    {
        Array.Sort(nums);//对nums数组进行排序
        int n=nums.Length,closestSum=nums[0]+nums[1]+nums[2],
            largestSum=nums[n-1]+nums[n-2]+nums[n-3];
        //如果最小的三个数和大于target,直接返回
        if(closestSum>=target)  return closestSum;
        //如果最大的三个数和小于target,直接返回
        if(largestSum<=target)  return largestSum;
        for(int i=0;i<n-2;i++)
        {
            //计算当前位置可能的最小三数之和
            int minSum=nums[i]+nums[i+1]+nums[i+2];
            //如果最小和已经大于target,后面的组合只会更大
            if(minSum>target)  return Math.Abs(minSum-target)<Math.Abs(closestSum-target)? minSum:closestSum;

        int left=i+1,right=n-1;
        while(left<right)
        {
            int currentSum = nums[i]+nums[left]+nums[right];
            if(currentSum==target)  return currentSum;
            if(Math.Abs(currentSum-target)<Math.Abs(closestSum-target))
                closestSum=currentSum;
            if(currentSum<target) left++;
            else  right--;
        }
        }
        return closestSum;
    }
}