banner
darkan

darkan

Array

First Method (Closed Left and Closed Right)#

// First Method
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // Define the target in the closed interval [left, right]
        while (left <= right) { // When left == right, the interval [left, right] is still valid, so use <=
            int middle = left + ((right - left) / 2); // Prevent overflow, equivalent to (left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target is in the left interval, so [left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target is in the right interval, so [middle + 1, right]
            } else { // nums[middle] == target
                return middle; // Found the target value in the array, return the index directly
            }
        }
        // Target value not found
        return -1;
    }
};

Second Method (Closed Left and Open Right)#

// Version Two
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // Define the target in the closed left and open right interval, i.e., [left, right)
        while (left < right) { // Because when left == right, it is an invalid space in [left, right), so use <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target is in the left interval, in [left, middle)
            } else if (nums[middle] < target) {
                left = middle + 1; // target is in the right interval, in [middle + 1, right)
            } else { // nums[middle] == target
                return middle; // Found the target value in the array, return the index directly
            }
        }
        // Target value not found
        return -1;
    }
};

Two Pointers Method#

Remove Element#

The two pointers method (fast and slow pointers): completes the work of two for loops with one for loop using a fast pointer and a slow pointer.
Define fast and slow pointers:

  • Fast pointer: finds elements for the new array, which is the array without the target element.
  • Slow pointer: points to the position of the updated new array index.
// Time complexity: O(n)
// Space complexity: O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
            if (val != nums[fastIndex]) {
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;
    }
};

Square of a Sorted Array#

class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        int k = A.size() - 1;
        vector<int> result(A.size(), 0);
        for (int i = 0, j = A.size() - 1; i <= j;) { // Note that here i <= j, because we need to handle two elements at the end
            if (A[i] * A[i] < A[j] * A[j])  {
                result[k--] = A[j] * A[j];
                j--;
            }
            else {
                result[k--] = A[i] * A[i];
                i++;
            }
        }
        return result;
    }
};

Sliding Window#

The so-called sliding window is constantly adjusting the starting and ending positions of the subsequence to derive the desired result.
The window is the smallest continuous subarray whose sum ≥ s.
How to move the starting position of the window: If the current value of the window is greater than or equal to s, the window needs to move forward (which means it should shrink).
How to move the ending position of the window: The ending position of the window is the pointer that traverses the array, which is the index in the for loop.
image.png|450
The brilliance of the sliding window lies in continuously adjusting the starting position of the subsequence based on the size of the current subsequence sum, thereby reducing the O(n^2) brute force solution to O(n).

Minimum Length of Subarray#

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0; // Sum of the sliding window values
        int i = 0; // Starting position of the sliding window
        int subLength = 0; // Length of the sliding window
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // Note that here we use while, updating i (starting position) each time and continuously comparing whether the subsequence meets the condition
            while (sum >= s) {
                subLength = (j - i + 1); // Get the length of the subsequence
                result = result < subLength ? result : subLength;
                sum -= nums[i++]; // This reflects the essence of the sliding window, constantly changing i (the starting position of the subsequence)
            }
        }
        // If result has not been assigned, return 0, indicating no subsequence meets the condition
        return result == INT32_MAX ? 0 : result;
    }
};

Spiral Matrix II#

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0)); // Use vector to define a two-dimensional array
        int startx = 0, starty = 0; // Define the starting position for each loop
        int loop = n / 2; // How many times each loop runs, for example, if n is odd 3, then loop = 1, just loop once, the middle value of the matrix needs to be handled separately
        int mid = n / 2; // The middle position of the matrix, for example: if n is 3, the middle position is (1,1), if n is 5, the middle position is (2, 2)
        int count = 1; // Used to assign values to each space in the matrix
        int offset = 1; // Needs to control the length of each edge traversed in each loop, shrinking the right boundary by one each time
        int i,j;
        while (loop --) {
            i = startx;
            j = starty;

            // The following four for loops simulate a complete loop
            // Simulate filling the upper row from left to right (closed left and open right)
            for (j; j < n - offset; j++) {
                res[i][j] = count++;
            }
            // Simulate filling the right column from top to bottom (closed left and open right)
            for (i; i < n - offset; i++) {
                res[i][j] = count++;
            }
            // Simulate filling the lower row from right to left (closed left and open right)
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            // Simulate filling the left column from bottom to top (closed left and open right)
            for (; i > startx; i--) {
                res[i][j] = count++;
            }

            // When starting the second loop, the starting positions need to be incremented by 1, for example: the starting position of the first loop is (0, 0), the starting position of the second loop is (1, 1)
            startx++;
            starty++;

            // Offset controls the length of each edge traversed in each loop
            offset += 1;
        }

        // If n is odd, need to assign a value to the middle position of the matrix separately
        if (n % 2) {
            res[mid][mid] = count;
        }
        return res;
    }
};

Summary#

image.png|650

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.