記事ディレクトリ
タイトル説明
暴力による解決
class Solution {
public int threeSumClosest(int[] nums, int target) {
if(nums==null||nums.length<3)
return 0;
int sum = Integer.MAX_VALUE;//记录和
int dlter = Integer.MAX_VALUE;//记录间隔
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
for(int k=j+1;k<nums.length;k++){
int res = nums[i]+nums[j]+nums[k];
int dlter_before = res-target;
if(Math.abs(dlter_before)<Math.abs(dlter)){
dlter = dlter_before;
sum = res;
}
}
}
}
return sum;
}
}
効率は感動的です。
最適化1を開始します。
class Solution {
public int threeSumClosest(int[] nums, int target) {
if(nums==null||nums.length<3)
return 0;
if(nums.length==3){
return nums[0]+nums[1]+nums[2];
}
Arrays.sort(nums);
int sum = Integer.MAX_VALUE;//记录和
int dlter = Integer.MAX_VALUE;//记录间隔
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length;j++){
if((sum-target)==0){
return sum;
}
// if(sum!=Integer.MAX_VALUE&&(nums[i]+nums[j]>target)&&nums[j]>=0){
// if(j+1<nums.length)
// sum = nums[i]+nums[j]+nums[j+1];
// return sum;
// }
int res1 = nums[i]+nums[j];
if(res1>target&&nums[j]>=0&&sum!=Integer.MAX_VALUE){
//无需枚举k
break;
}
for(int k=j+1;k<nums.length;k++){
int res = nums[i]+nums[j]+nums[k];
int dlter_before = res-target;
if(Math.abs(dlter_before)<Math.abs(dlter)){
dlter = dlter_before;
sum = res;
if(dlter_before>0)//k是升序的,大于0则后面的都不需要枚举了。
break;
}
}
}
}
return sum;
}
}
最適化を開始する2:ダブルポインター
原則として、それはまだ3層のサイクルです。ループの1つの層を削除する必要があります。このような問題を最適化するためにダブルポインターを使用できると考えています。それで私は自分の考えを始めました。
デュアルポインターは一般にデータの法則を使用して実行されます。
class Solution {
public int threeSumClosest(int[] nums, int target) {
if(nums==null||nums.length<3)
return 0;
if(nums.length==3){
return nums[0]+nums[1]+nums[2];
}
Arrays.sort(nums);
int dlt = Integer.MAX_VALUE;//记录间隔
int res = Integer.MAX_VALUE;
for(int i=0;i<nums.length-2;i++){
int k = nums.length-1;//指针k
for(int j=i+1;j<nums.length-1&&k>j;){
//指针j
int res_now = nums[i]+nums[j]+nums[k];
int dlt_now = Math.abs(res_now-target);
if(res_now>target){
//如果当前的值大于target,说明了 我们如果想要找到比该值更接近的数只能让k--。在这个过程里面 还需要进行更新操作,即如果当前的间距更加小。则更新记录的值
if(dlt_now<dlt){
res = res_now;
dlt = dlt_now;
}
k--;
}else if(res_now<target){
//如果当前的值小于 target,说明我们需要移动j,在这个过程里面 还需要进行更新操作,即如果当前的间距更加小。则更新记录的值
if(dlt_now<dlt){
res = res_now;
dlt = dlt_now;
}
j++;
}else return res_now; //如果相等则直接返回。相等是最小的间距
}
}
return res;
}
}
複雑さの分析:
時間の複雑さ:O(N 2);
空間の複雑さ:O(log N)。ソートにはO(logN)スペースが必要です。ただし、実際の状況では必ずしも許可されない入力配列numsを変更したため、追加の配列を使用してnumsのコピーを格納し、それを並べ替えていると見なすこともできます。現時点では、スペースの複雑度はO(N)です。