leetcode三数の和--二重ポインタ
タイトルリンク:三数の和タイトル説明:n個の整数を含む配列numsをあげて、numsの中に3つの要素a,b,cが存在するかどうかを判断して、a+b+c=0にしますか?条件を満たし、繰り返さないすべての三元グループを見つけてください.
注意:答えに重複する三元グループは含まれてはいけません.
例:
与えられた配列nums=[−1,0,1,2,−1,−4],
要求を満たす三元群の集合は,[[−1,0,1],[−1,−1,2]]である.
テーマ分析:肝心なのは繰り返さないことで、それでは繰り返さないために、まず配列を並べ替えることができて、同時に遍歴の過程の中で循環の下のスケールと隣接する要素が等しいかどうかの判断を制御して、重み付けの目的を達成します.続けて言えば、3つの数の和が固定されているため、私たちはその中の2つの数を知った後、3番目の数が確定しているので、1つの数を固定し、他の2つの数を列挙することができます.他の2つの数和は決定され、そのうちの1つが大きくなると、もう1つは必ず減少するので、2つのポインタを用いて双方向並列遍歴を行い、時間の複雑さを減少させることができる.本題の「二重ポインタ」では,配列中の2つの要素を列挙する必要がある場合,第1の要素が増加するにつれて第2の要素が減少することが分かった場合,二重ポインタ法を用いて,列挙の時間的複雑さをO(N 2)からO(N)に減少させることができる.なぜO(N)なのか.これは、列挙の過程の各ステップにおいて、「左ポインタ」が右に1つの位置(すなわち、タイトルのb)を移動し、「右ポインタ」が左にいくつかの位置を移動するため、配列の要素に関係するが、合計で移動する位置数はO(N)であり、均等に割り当てられ、毎回左に1つの位置を移動するため、時間の複雑さはO(N)であることが知られているからである.
コード:
似たような問題を補充します:最も近い3数の和はこの問題とほとんど同じ考えです
注意:答えに重複する三元グループは含まれてはいけません.
例:
与えられた配列nums=[−1,0,1,2,−1,−4],
要求を満たす三元群の集合は,[[−1,0,1],[−1,−1,2]]である.
テーマ分析:肝心なのは繰り返さないことで、それでは繰り返さないために、まず配列を並べ替えることができて、同時に遍歴の過程の中で循環の下のスケールと隣接する要素が等しいかどうかの判断を制御して、重み付けの目的を達成します.続けて言えば、3つの数の和が固定されているため、私たちはその中の2つの数を知った後、3番目の数が確定しているので、1つの数を固定し、他の2つの数を列挙することができます.他の2つの数和は決定され、そのうちの1つが大きくなると、もう1つは必ず減少するので、2つのポインタを用いて双方向並列遍歴を行い、時間の複雑さを減少させることができる.本題の「二重ポインタ」では,配列中の2つの要素を列挙する必要がある場合,第1の要素が増加するにつれて第2の要素が減少することが分かった場合,二重ポインタ法を用いて,列挙の時間的複雑さをO(N 2)からO(N)に減少させることができる.なぜO(N)なのか.これは、列挙の過程の各ステップにおいて、「左ポインタ」が右に1つの位置(すなわち、タイトルのb)を移動し、「右ポインタ」が左にいくつかの位置を移動するため、配列の要素に関係するが、合計で移動する位置数はO(N)であり、均等に割り当てられ、毎回左に1つの位置を移動するため、時間の複雑さはO(N)であることが知られているからである.
コード:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int i = 0,l ,r,sum;
while(i < nums.length-2&&nums[i]<=0){
l = i+1;
r = nums.length-1;
while(l<r){
sum = nums[l]+nums[i]+nums[r];
if(sum==0){
res.add(Arrays.asList(nums[l++],nums[i],nums[r--]));
//
while(l<r&&nums[l]==nums[l-1]) l++;
while(l<r&&nums[r]==nums[r+1]) r--;
}else if(sum<0){
l++;
}else
r--;
}
i++;
//
while(i<nums.length-2&&nums[i]==nums[i-1]) i++;
}
return res;
}
}
似たような問題を補充します:最も近い3数の和はこの問題とほとんど同じ考えです
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int ans = 1000000;
for(int i = 0;i < nums.length;i++){
if(i>0&&nums[i]==nums[i-1]) continue;
int j = i + 1, k = nums.length-1;
while(j<k){
int sum = nums[i]+nums[j]+nums[k];
if(sum==target) return target;
if(Math.abs(sum-target)<Math.abs(ans-target))
ans = sum;
if(sum>target){
k--;
while(j<k&&nums[k]==nums[k+1]) k--; // ,
}else{
j++;
while(j<k&&nums[j]==nums[j-1]) j++;//
}
}
}
return ans;
}
}