タイトルの説明
n個の整数を含む配列numsを与え、a + b + c = 0となるようなnumsに3つの要素a、b、cがあるかどうかを判断しますか?条件を満たす、繰り返されないすべてのトリプルを見つけてください。
注:回答に繰り返しトリプルを含めることはできません。
例:
配列nums = [-1、0、1、2、-1、-4]の場合
、要件を満たすトリプルのセットは次のとおりです。
[
[-1、0、1]、
[-1、-1 、2]
]]
アイデア:
最初に配列を並べ替え、
結果の
固定配列に数値num [i]を格納するリストを作成してから、ダブルポインターを使用して、数値の左端と右端をポイントします(nums [left]、nums [right ])、数値と2つのポインタが指す数値の合計を計算します。0の場合は、結果セットに追加されます。
num [i]が0より大きい場合、次の数値は0より大きいため、3つの数値の合計が0であってはならず、ループは終了します
。num[i] == num [i-1]の場合、数値が繰り返されてスキップされます;
合計が0の場合、結果セットに追加されます。nums[left] = nums [left + 1]の場合、結果が繰り返されます、left ++; nums [right] = nums [right-1]の場合、結果は繰り返されます、右–;
コード:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
for(int i = 0;i<nums.length-2;i++){
int left = i+1;
int right = nums.length - 1;
if(nums[i] >0){
return res;
}
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
while(left < right){
int sum = nums[i]+nums[left]+nums[right];
if(sum == 0){
res.add(Arrays.asList(new Integer[]{
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 res;
}
}
3つの数値の最も近い合計
問題の説明
n個の整数を含む配列numとターゲット値targetが与えられます。それらの合計がターゲットに最も近くなるように、numsで3つの整数を見つけます。これらの3つの数値の合計を返します。入力のセットごとに1つの答えしかないと仮定します。
入力:nums = [-1,2,1、-4]、target = 1
出力:2
説明:targetに最も近い合計は2(-1 + 2 + 1 = 2)です。
考え方は基本的に前の質問と同じ
です。3つの数値の合計とターゲットの差を記録するためにdiff変数を追加する必要があり、closeSum変数は3つの数値の最も近い合計を記録します。現在の3つの数値の合計が多い場合は、
nums [left]とnums [left + 1]、nums [right]とnums [right-1](前の質問は繰り返し不可)のサイズの関係を判断する必要はありません。
ターゲットの差よりもdiffが小さい場合は、diff値を更新し、closeSum値も更新します。
現在の3つの数値の合計がターゲットよりも小さい場合は、left ++で、合計を大きくします。
現在の合計が3の場合数値が目標よりも大きく、次に右–、合計が小さくなります
コード:
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int diff = Integer.MAX_VALUE;
int closeSum = 0;
for(int i = 0;i<nums.length-2;i++){
int left = i+1;
int right = nums.length-1;
int sum = 0;
int tempdiff = 0;
while(left < right){
sum = nums[i] + nums[left] + nums[right];
tempdiff = Math.abs(sum-target);
if(tempdiff < diff){
closeSum = sum;
diff = tempdiff;
}
if(sum < target){
left++;
}else if (sum > target){
right--;
}else{
return closeSum;
}
}
}
return closeSum;
}
}