目录
LeetCode 第14题:最长公共前缀
题目描述
编写一个函数来查找字符数组中的最长公共前缀。如果不存在公共前缀,返回字符串“”。
难度:简单
示例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且不重复的三元组。注意:答案中不可以包含重复的三元组。
难度:中等
示例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]:
- 如果nums[i]>0,因为数组已排序,后面不可能有三个数字之和为0
- 如果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最接近。返回这三个数的和,假定每组输入只存在恰好一个解。
难度:中等
示例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; } }