1.問題の説明:
整数配列numsとターゲット値targetを指定して、合計が配列内のターゲット値である2つの整数を見つけ、それらの配列インデックスを返します。
各入力は1つの回答にのみ対応すると想定できます。ただし、この配列で同じ要素を再利用することはできません。
例:
数値= [2、7、11、15]、ターゲット= 9
nums [0] + nums [1] = 2 + 7 = 9
なので、[0、1]を返します
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/two-sum
2.思考分析:
①問題は理解しやすく、最初は再帰を使って解くことを考えました。再帰的な方法では、2つのポインターが使用されます。1つは左ポインターで、もう1つは右ポインターです。計算時に2つの可能な演算を使用できます。 、1つは、左ポインターが1ビット移動し、右ポインターは移動しないことです。もう1つは、左ポインターが移動せず、右ポインターが1ビット左に移動するため、2つの並列状態に対応するため、2つの方法が使用されます。再帰するだけで、2次元配列を使用して、再帰中にソリューションの結果を記録します。ソリューションが以前に解決されたことを再帰的に見つけた後、直接戻るが、送信時にメモリ制限を超えた場合、データである可能性があります量が多すぎるため、別の方法を使用して解決します
②再帰的タイムアウトを利用するため、マッピングはmapを使用しており、最初は配列全体をトラバースし、配列内の対応する値をその値に対応する次の表にマッピングし、Deque型の値で2つの問題を回避できます。配列の要素は同じです。mapを使用して配列の値と添え字をマッピングするのは、主に、ソート後にソートする前に数値に対応する添え字の値を見つけることです。mapを使用して、ループ内の配列をマッピングおよびソートします。左と右のポインタを使用して操作します。左のポインタが小さすぎる場合、2つの要素が等しくなるまで右のポインタが左に移動するため、再帰的なタイムアウトの問題を回避できます。
③公式の解決策では、最大2つの数値が問題に現れる状況を組み合わせます。したがって、forループトラバーサルをハッシュテーブルと組み合わせて使用して解決し、減算を使用して解決時に別の数値を見つけますマッピング状況、繰り返し数のマッピングの問題とクエリの効率の解決から、書かれたコードは非常に良いです
3.コードは次のとおりです。
私が自分で書いたコード:
class Solution {
public int[] twoSum(int[] nums, int target) {
int res[] = new int[2];
Map<Integer, Deque<Integer>> map = new HashMap<>();
/*使用map来进行记录*/
for (int i = 0; i < nums.length; ++i){
map.put(nums[i], map.getOrDefault(nums[i], new ArrayDeque()));
map.get(nums[i]).add(i);
}
Arrays.sort(nums);
/*使用快慢指针来解决*/
int l = 0, r = nums.length - 1;
while (l < r){
if (nums[l] + nums[r] == target){
res[0] = map.get(nums[l]).pop();
res[1] = map.get(nums[r]).pop();
return res;
}else if (nums[l] + nums[r] < target) ++l;
else --r;
}
return null;
}
}
class Solution {
int res[] = new int[2];
int rec[][];
public int[] twoSum(int[] nums, int target) {
rec = new int[nums.length][nums.length];
recursion(nums, target, 0, nums.length - 1);
return res;
}
/*使用一个数组来记录中间的求解过程*/
private void recursion(int[] nums, int target, int l, int r) {
if (l >= r) return;
if (rec[l][r] == -1) return;
if (nums[l] + nums[r] == target){
res[0] = l;
res[1] = r;
return;
}
/*存在两个平行的状态: l加r不变, l不变r减*/
recursion(nums, target, l + 1, r);
recursion(nums, target, l, r - 1);
rec[l][r] = -1;
}
}
公式コード:
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
}