Array knowledge points and leetcode questions

array


binary search

topic

Click on the question link

Given an n-element sorted (ascending) integer array nums and a target value target, write a function that searches target in nums and returns the subscript if the target value exists, otherwise it returns -1.

Scope of application

The array is ordered and there are no duplicate elements in the array

Ideas

Find the midpoint of the array each time and compare it with the target value.

  • if(nums[mid] > target ) high = mid - 1
  • else if((nums[mid] < target )) low = mid + 1
  • else found, returns the corresponding subscript

Loop termination condition judgment, while(low <= high) At this time, low == high is meaningful, so an equal sign must be added.

C++ code

class Solution { 
    public:     
    int search(vector<int>& nums, int target) {         
        //二分查找         
        int n = nums.size();         
        int left = 0, right = n - 1;                    //定义初始查找边界为左闭右闭
        while(left <= right){                           //等号要加上             
            int mid = left + (right - left)/2;          //等同于 (left+right)/2,防止数组溢出
            if(nums[mid] > target) right = mid - 1;     //在左半部分查找             
            else if(nums[mid] < target) left = mid + 1; //在右半部分查找             
            else return mid;                            //找到,返回对应下标         
        }         
        return -1;                                      //未找到,返回-1      
    } 
};

//在c++的语法当中,存在内置函数进行二分的查找,在编程的时候可以采用内置函数的方法
//lower_bound(val),在数组中找到大于等于val值的第一个元素下标位置
//upper_bound(val),在数组中找到大于val值的第一个元素下标位置
//时间复杂度为O(logn)
//空间复杂度为O(1)

JAVA code

class Solution {
    
    
    public int search(int[] nums, int target) {
    
    
        int len = nums.length;
        int low = 0, high = len - 1, mid;
        while(low <= high){
    
    
            mid = low + (high - low)/2;
            if(nums[mid] > target) high = mid - 1;
            else if(nums[mid] < target) low = mid + 1;
            else return mid;
        }
        return -1;
    }
}

Remove element

topic

Click on the question link

Given an array nums and a value val, you need to remove in place all elements whose value is equal to val and return the new length of the array after removal. Instead of using extra array space, you have to use only O(1) extra space and modify the input array in place.

Ideas

The elements of the array are continuous in the memory address. An element in the array cannot be deleted individually, but can only be overwritten.

Therefore, double pointer writing is used to overwrite the original memory.

C++ code

Writing method one
  • Define fast and slow pointers
    • The left pointer is used as a slow pointer to update the element subscript and store elements that are not equal to the val value.
    • The right pointer is used as a fast pointer to traverse the array.

Once in the loop, left will move only if the right pointer is not equal to the value val.

class Solution { 
    public:     
    int removeElement(vector<int>& nums, int val) {         
        //双指针,当数组下表为val的时候,left不移动,只有当数组值不为val的时候,left才进行移动
        int n = nums.size();         
        int left=0;         //left作为数组的存储下标,存储不等于val值的元素                  
        int right = 0;      //right作为遍历数组的下标          
        for(right = 0; right < n; right++){             
            if(nums[right] != val){                 
                nums[left++] = nums[right];             
            }         
        }         
        return left;     
    } 
};
// 时间复杂度:O(n) 
// 空间复杂度:O(1)

JAVA code

class Solution {
    
    
    public int removeElement(int[] nums, int val) {
    
    
        //双指针
        int left = 0, right = 0;
        int n = nums.length;
        while(right < n){
    
    
            if(nums[right] != val){
    
    
                nums[left++] = nums[right];
            }
            right++;
        }
        return left;
    }
}
Writing method two

Similar to the idea of ​​quick sort, the left pointer is used to find elements equal to the val value, and the right pointer is used to find elements not equal to the val value, and then after finding them, the elements are exchanged, < a i=1>This writing changes the relative position between elements.

    class Solution { 
    public:     
    int removeElement(vector<int>& nums, int val) {     
		/*写法二
        也是双指针写法,但是与第一种有些区别。左右指针,一个从头开始找元素等于val,一个从末尾开始找不是val的,然后元素之间的值进行交换
        */
        int n = nums.size();
        int left = 0, right = n - 1;
        while(left <=  right){
            while(left <= right && nums[left] != val) left++;
            while(left <= right && nums[right] == val) right--;
            if(left <= right){
                nums[left++] = nums[right--];
            }
        }
        return left;
    }
};

JAVA code

class Solution {
    
    
    public int removeElement(int[] nums, int val) {
    
    
        int n = nums.length;
        int left = 0, right = n - 1;
        while(left <=  right){
    
    
            while(left <= right && nums[left] != val) left++;
            while(left <= right && nums[right] == val) right--;
            if(left <= right){
    
    
                nums[left++] = nums[right--];
            }
        }
        return left;
    }
}

square of ordered array

topic

Click on the question link

Gives you an integer array sorted innon-decreasing ordernums and returns< a i=4>The new array composed of the square of each number is also required to be sorted in non-decreasing order.

Ideas

Double pointer solution

A pointer is compared from the beginning,

A pointer is compared starting from the end,

If the number is large, put it at the end, and then subtract 1 from the corresponding subscript.

A pointer is moved backward on each comparison for counting.

C++ code

  • Define left and right pointers
    • The i pointer is used as a left pointer to compare the largest element of a negative number.
    • The j pointer is used as a right pointer to compare the largest element of a positive number.
    • The pos pointer is used to simulate the movement of subscripts
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        //双指针解法
        int n = nums.size();
        vector<int> ans(n,0);
        int i = 0, j = n - 1, pos = n - 1;
        while(pos >= 0){
            if(nums[i] * nums[i] > nums[j] * nums[j]){
                ans[pos--] = nums[i]*nums[i];
                i++;
            }
            else{
                ans[pos--] = nums[j]*nums[j];
                j--;
            }
        }
        return ans;
    }
};
// 时间复杂度:O(n) 
// 空间复杂度:O(n)

Java code

class Solution {
    
    
    public int[] sortedSquares(int[] nums) {
    
    
         //双指针解法
        int n = nums.length;
        int ans[] = new int[n];
        int i = 0, j = n - 1, pos = n - 1;
        while(pos >= 0){
    
    
            if(nums[i] * nums[i] > nums[j] * nums[j]){
    
    
                ans[pos--] = nums[i]*nums[i];
                i++;
            }
            else{
    
    
                ans[pos--] = nums[j]*nums[j];
                j--;
            }
        }
        return ans;
    }
}

subarray with minimum length

topic

Click on the question link

Given a containing n 个正整数的数组和一个正整数 target .

Find the smallest continuous subarray in the array whose sum is greater than or equal to target, and returns its length**. **If there is no subarray that meets the condition, return . [numsl, numsl+1, ..., numsr-1, numsr]0

Ideas

Classic sliding window idea question

is also a solution similar to double pointers. Two pointers are defined, left and right, respectively representing the left and right boundaries of the sliding window, while maintaining a variable sum. Store the subarray, which is the sum of the elements of the sliding window.

  • Begin,leftJapaneserightToward 0
  • Then the right pointer keeps moving forward, and then num[end] is added to sum
  • If sum is greater than s, it means that the left boundary pointer, which is left, can be updated at this time. This Get the current shortest sliding window value, and then the left pointer keeps moving. At this time, you need to subtract the values ​​that are no longer in the sliding window
  • Keep iterating until the right pointer reaches the end of the array, and you're done.

c++ code

  • Define left and right pointers
    • The i pointer serves as the left pointer and serves as the left boundary of the sliding window
    • The j pointer serves as the right pointer and serves as the right boundary of the sliding window
    • sum is used to calculate the total of the sliding window to facilitate the update of the left and right pointers.
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        //滑动窗口典型代表题目
        int n = nums.size();
        int minSize = n + 1;            //初始化滑动窗口的长度为n+1
        int flag = 0;
        int i = 0, j = 0;
        int sum = 0;
        while(j < n){
                sum+=nums[j++];         //右指针往后移动
            while(sum >= target){       //滑动窗口总和大于target时,可以求最小滑动窗口的长度,以及更新左指针
                minSize = min(j - i, minSize);
                sum -= nums[i++];       //左指针不断往后移动
            }
        }
        //三目运算符,如果滑动窗口的值没有进行改变的话,说明是不存在
        return minSize == n + 1 ? 0 : minSize;
    }
};

Java code

class Solution {
    
    
    public int minSubArrayLen(int target, int[] nums) {
    
    
        //滑动窗口典型代表题目
        int n = nums.length;
        int minSize = n + 1;            //初始化滑动窗口的长度为n+1
        int flag = 0;
        int i = 0, j = 0;
        int sum = 0;
        while(j < n){
    
    
                sum+=nums[j++];         //右指针往后移动
            while(sum >= target){
    
           //滑动窗口总和大于target时,可以求最小滑动窗口的长度,以及更新左指针
                minSize = Math.min(j - i, minSize);
                sum -= nums[i++];       //左指针不断往后移动
            }
        }
        //三目运算符,如果滑动窗口的值没有进行改变的话,说明是不存在
        return minSize == n + 1 ? 0 : minSize;
    }
}

Spiral Matrix II

topic

Click on the question link

Give you a positive integern, generate an array containing all elements from 1 to n2, and the elements are in clockwise order Sequentially spirally arrangedn x n square matrixmatrix .

Idea 1

  • For simulation questions, a loop is set up to represent a few clockwise turns, and then the left and right boundaries are simulated based on the number of circles.

  • Simulate the process of drawing a matrix clockwise:

    • Fill the upper row from left to right
    • Fill right column from top to bottom
    • Fill down rows from right to left
    • Fill left column from bottom to top
  • One of the more noteworthy points here is that a code plan needs to be maintained here, which is the issue of left and right boundaries.Each edge needs to follow the principle of closing the left and opening the right.

  • Another thing to note is that the loop here is an odd number, so if n is an odd number, the last middle number will be left unfilled, so at the end you need to determine whether n is an odd number.

C++ code

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> matrix(n, vector<int>(n));
        int i = 0, j = 0, loop = 0;
        int num = 1;
        //螺旋矩阵,最重要的几个点,根据圈数来决定是否要结束循环
        //每次循环的左右边界都需要确定好,是左闭右开,还是左闭右闭
        //圈数如果为偶数,直接循环遍历,但是如果圈数为奇数的话,就需要对最里面的一个数单独赋值
        while(loop < n/2){
            //最上面的一行,根据圈数来决定起始位置\终止位置和每圈的个数,列在增大
            for(i = loop; i < n-loop-1; i++)  matrix[loop][i] = num++;

            //最右边的一行,根据圈数来决定起始位置\终止位置和每圈的个数,行在增大
            for(j = loop; j < n-loop-1; j++) matrix[j][n-loop-1] = num++;

            //最下面的一行,根据圈数来决定起始位置\终止位置和每圈的个数,列在减小,初始值可以利用前面的i
            for(;i > loop; i--)  matrix[n-loop-1][i] = num++;

            //最左边的一行,根据圈数来决定起始位置\终止位置和每圈的个数,行在减小,初始值可以利用前面的j
            for(;j > loop; j--) matrix[j][loop] = num++;

            //循环完一圈,继续下一圈
            loop++;
        }

        //如果圈数为奇数,需要对最里面的数单独赋值
        if(n % 2)
            matrix[loop][loop] = num;
        return matrix;
    }
};

Java code

class Solution {
    
    
    public int[][] generateMatrix(int n) {
    
    
        int matrix[][] = new int[n][n];
        int i = 0, j = 0, loop = 0;
        int num = 1;
        //螺旋矩阵,最重要的几个点,根据圈数来决定是否要结束循环
        //每次循环的左右边界都需要确定好,是左闭右开,还是左闭右闭
        //圈数如果为偶数,直接循环遍历,但是如果圈数为奇数的话,就需要对最里面的一个数单独赋值
        while(loop < n/2){
    
    
            //最上面的一行,根据圈数来决定起始位置\终止位置和每圈的个数,列在增大
            for(i = loop; i < n-loop-1; i++)  matrix[loop][i] = num++;

            //最右边的一行,根据圈数来决定起始位置\终止位置和每圈的个数,行在增大
            for(j = loop; j < n-loop-1; j++) matrix[j][n-loop-1] = num++;

            //最下面的一行,根据圈数来决定起始位置\终止位置和每圈的个数,列在减小,初始值可以利用前面的i
            for(;i > loop; i--)  matrix[n-loop-1][i] = num++;

            //最左边的一行,根据圈数来决定起始位置\终止位置和每圈的个数,行在减小,初始值可以利用前面的j
            for(;j > loop; j--) matrix[j][loop] = num++;

            //循环完一圈,继续下一圈
            loop++;
        }

        //如果圈数为奇数,需要对最里面的数单独赋值
        if(n % 2 == 1)
            matrix[loop][loop] = num;
        return matrix;
    }
}

Idea 2

  • sets the upper, lower, left and right boundaries, and simulates four values. The overall difficulty of understanding and simulation is much simpler than the first idea. The code implementation also needs to abide by the boundary consistency principle. Here we use left-closed and right-closed.
  • Simulate the process of drawing a matrix clockwise:
    • Fill the upper row from left to right
    • Fill right column from top to bottom
    • Fill down rows from right to left
    • Fill left column from bottom to top

C++ code

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> matrix(n, vector<int>(n));
        //模拟,设置上下左右边界,每次遍历完某一行或者某一列,边界进行换
        int num = 1;
        //设置上下左右边界
        int left = 0, high = 0, right = n - 1, low = n - 1;
        while(true){
            for(int i = left; i <= right; i++) matrix[high][i] = num++;
            if(++high > low)  break;

            for(int j = high; j <= low; j++) matrix[j][right] = num++;
            if(--right < left) break;

            for(int i = right; i >= left; i--) matrix[low][i] = num++;
            if(--low < high) break;

            for(int j = low; j >= high; j--) matrix[j][left] = num++;;
            if(++left > right) break;
        }
        return matrix;
    }
};

Java code

class Solution {
    
    
    public int[][] generateMatrix(int n) {
    
    
        int matrix[][] = new int[n][n];
        //模拟,设置上下左右边界,每次遍历完某一行或者某一列,边界进行换
        int num = 1;
        //设置上下左右边界
        int left = 0, high = 0, right = n - 1, low = n - 1;
        while(true){
    
    
            for(int i = left; i <= right; i++) matrix[high][i] = num++;
            if(++high > low)  break;

            for(int j = high; j <= low; j++) matrix[j][right] = num++;
            if(--right < left) break;

            for(int i = right; i >= left; i--) matrix[low][i] = num++;
            if(--low < high) break;

            for(int j = low; j >= high; j--) matrix[j][left] = num++;;
            if(++left > right) break;
        }
        return matrix;
    }
}

Guess you like

Origin blog.csdn.net/m0_46335449/article/details/134064599