1 2つの数値の合計(マップ、高速および低速ポインター)

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");
    }
}

 

元の記事569件を公開 153のような 訪問数590,000+

おすすめ

転載: blog.csdn.net/qq_39445165/article/details/105423280