LeetCode--Dual pointer

Topic 1: Search in a two-dimensional array

(2021/1/1)

In an n * m two-dimensional array, each row is sorted in increasing order from left to right, and each column is sorted in increasing order from top to bottom. Please complete an efficient function, input such a two-dimensional array and an integer to determine whether the array contains the integer.

Example:

The existing matrix is ​​as follows:

[
  [1, 4, 7, 11, 15],
  [2, 5, 8, 12, 19],
  [3, 6, 9, 16, 22],
  [10, 13, 14, 17, 24],
  [ 18, 21, 23, 26, 30]
]
Given target = 5, return true.

Given target = 20, return false

One's own method: Violent traversal: double for loop, the code is relatively simple

Own method 2: According to the characteristics of matrix sorting, set a row mark and column mark, and search from the lower left or upper right corner of the matrix

Java source code

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        int row = matrix.length - 1;
        int col = 0;
        while (row >= 0 && col < matrix[0].length) {
            if (matrix[row][col] == target) {
                return true;
            } else if (matrix[row][col] > target) {
                row--;
            } else if (matrix[row][col] < target) {
                col++;
            }
        }
        return false;
    }
}

Topic 2: Sum of Three Numbers

(2021/1/4) Link: https://leetcode-cn.com/problems/3sum

Given an array nums containing n integers, determine whether there are three elements a, b, c in nums, such that a + b + c = 0? Please find all the triples that meet the conditions and are not repeated.

Note: The answer cannot contain repeated triples.

Example:

Given the array nums = [-1, 0, 1, 2, -1, -4],

The set of triples that meet the requirements are:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

Method 1: My own thinking is a triple loop, and I can't think of a better method.

Method two: official answer: sort + double pointer

Double pointer method foreshadowing: first sort the given nums, the complexity is O(NlogN)O(NlogN).
The idea of ​​the double pointer method: Fix the pointer k of the leftmost (minimum) number among the 33 pointers. The double pointers i and j are set at the two ends of the array index (k, len(nums))(k,len(nums)). The pointers move to the middle alternately, and record all i, j combinations satisfying nums[k] + nums[i] + nums[j] == 0 for each fixed pointer k:
break out directly when nums[k]> 0 : Because nums[j] >= nums[i] >= nums[k]> 0, that is, 33 numbers are greater than 00, it is impossible to find the result after this fixed pointer k.
When k> 0 and nums[k] == nums[k-1], the element nums[k] is skipped: because all the combinations of nums[k-1] have been added to the result, this double pointer search Only duplicate combinations will be obtained.
i, j are set at the two ends of the array index (k, len(nums))(k,len(nums)), when i <j, loop calculation s = nums[k] + nums[i] + nums[j], And perform the double pointer movement according to the following rules:
when s <0, i += 1 and skip all repeated nums[i];
when s> 0, j -= 1 and skip all repeated nums[j] ;
When s == 0, record the combination [k, i, j] to res, execute i += 1 and j -= 1 and skip all repeated nums[i] and nums[j] to prevent repetitions from being recorded combination.
Complexity analysis:
1) Time complexity O(N^2)O(N 
2 ): The loop complexity of fixed pointer k is O(N)O(N), and the complexity of double pointer i, j is O(N)O( N).
Space complexity O(1)O(1): The pointer uses a constant amount of extra space.

Java source code:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> listresult = new ArrayList<>();
        Arrays.sort(nums);
        {
            for(int k = 0; k<nums.length-2;k++){
                if(nums[k]>0) return listresult;
                int i = k+1;
                int j = nums.length-1;
                if(k>0 &&nums[k]==nums[k-1]){
                    continue;
                }
                while(i<j){

                    if(nums[k]+nums[i]+nums[j] <0){
                        while(i<j &&nums[i] == nums[++i]);
                    }else if(nums[k]+nums[i]+nums[j]>0){
                        while(i<j && nums[j]== nums[--j]);
                    }
                    else{
                        List<Integer> templist = new ArrayList<>();
                        templist.add(nums[k]);
                        templist.add(nums[i]);
                        templist.add(nums[j]);
                        listresult.add(templist);
                        while(i<j &&nums[i] == nums[++i]);
                        while(i<j && nums[j]== nums[--j]);
                    }
                }
            }
        }
        return listresult;
    }
}

 

Guess you like

Origin blog.csdn.net/yezonghui/article/details/112055530