Data Structures and Algorithms (2) - Arrays and Related Algorithms

Basic knowledge of arrays

Introduction

Array (Array) is a linear table data structure. It uses a set of contiguous memory spaces to store a set of data of the same type.

A linear table is a structure in which data is arranged like a line. The data on each linear table has at most two directions, front and back. In fact, in addition to arrays, linked lists, queues, stacks, etc. are also linear table structures. The concept opposite to it is a nonlinear table, such as a binary tree, a heap, a graph, and so on. The reason why it is called non-linear is because, in a non-linear table, there is not a simple context between data.

Common operations

Take the following image array as an example:

insert image description here

read

Arrays support random reads, and the time complexity of random reads is O(1)

look up

Finding a specified value in an array (unsorted) requires traversing the array, and the time complexity is O(n)

insert

As shown in the figure, insert 10 to the position where k = 2.

insert image description here

If you insert elements at the end of the array, there is no need to move the data, and the time complexity is O(1). But if you insert an element at the beginning of the array, all the data needs to be shifted back one bit in turn, so
the worst time complexity is O(n). Because we have the same probability of inserting an element at each position, the average case time complexity is (1+2+...n)/n=O(n)

delete

Similar to insertion, the time complexity is O(n)

Common Algorithms Related to Arrays

The following algorithm questions are from Leetcode, the interview questions of various companies on Niuke.com, and the sample questions on "Jianzhi Offer". It is recommended to do more questions, and doing more questions is the kingly way.

double pointer (or double index)

Example 1: Leetcode's sum of two numbers II - input ordered array

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

Method 1: Use bidirectional traversal, but the time complexity is O(n^2)

Method 2: Using double pointers, the time complexity is O(n)

insert image description here

Use startto point to the start position and endto point to the end position. Determine the relationship nums[start] + nums[end]between the sum of and the target number target. Since the array is an ordered array , it is possible to nums[start] + nums[end] > targetrequire when ; similarly, when , requiresend--nums[start] + nums[end] == targetnums[start] + nums[end] < targetstart++

insert image description here
because nums[start] + nums[end] = 17 > target = 9, so end -- , getend = 2

insert image description here

nums[start] + nums[end] = 13 > target = 9, so end -- , get end = 1; the final calculation
nums[0] + nums[1] == 9, that is, get the result.

code show as below:

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        if(numbers == null || numbers.length <= 1)return new int[2];//判断输入数组是否合法
        int start = 0;
        int end = numbers.length - 1;
        while(start < end){
            int sum = numbers[start]+numbers[end];
            if(sum == target){
                break;
            }else if(sum > target){
                end--;
            }else{
                start++;
            }
        }
        int[] res = new int[2];
        res[0] = start+1;
        res[1] = end+1;
        return res;
    }
}

Example 2: The subarray with the smallest length

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 
的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0。

示例: 
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

insert image description here

as the picture shows:

Define two pointers i and j to point to 0 and 1 respectively; its sum = 2 + 3 < s = 7, so let j++ until its sum >= s; as shown in the third table, its sum = 8 > s = 7, record res = 4 at this time, and let i++; as shown in the figure, and so on,
you can get res = 2.

code show as below

class Solution {
    
    
    public int minSubArrayLen(int s, int[] nums) {
    
    
        if(nums == null || nums.length <= 0)return 0;
        int start = 0;
        int end = 1;
        int min = 1;
        int sum = nums[0];
        int res = Integer.MAX_VALUE;
        while(true){
    
    
           if(sum >= s){
    
    
               res = Math.min(min,res);
           } 
           if(sum > s){
    
    
               sum -= nums[start];
               min--;
               start++;
           }else{
    
    
               if(end >= nums.length)break;
               sum += nums[end];
               end++;
               min++;
           }
        }
        if(res == Integer.MAX_VALUE)return 0;
        return res;
    }
}

Use the quick sort algorithm idea

Example: The Kth largest element in an array (important, frequently asked in interviews)

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 
个最大的元素,而不是第 k 个不同的元素。

示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

Solution 1: sort the array first, and then we can get the elements we need through nums[nums.length - k]. Since the sorting algorithm is used, the time complexity of the algorithm is O(nlogn)

Solution 2: Using the principle of quick sorting, the k-th largest element can be obtained with only O(n) time complexity, which is also an algorithm that we need to understand in general interviews.

Algorithm idea: Randomly find a number p in the array, put the elements in the array that are larger than this number p on the right, and those that are smaller than p on the left, as shown in the figure
insert image description here
insert image description here

Then the position where p is located is index = 4, that is, p = 4 is the fourth smallest number in the array, otherwise, p = 4 is the third largest number in the array. Since p = 4 itself and the previous number cannot be the elements we need to find, so the elements of [0,3] are truncated, and the initial steps are repeated from the range of the array [4,5] to find the kth largest element.

insert image description here

As shown in the figure, when p = 5, it is the second largest element, that is, the result is returned.

The code implementation from the author liweiwei1419 is as follows

public class Solution {
    
    

    public int findKthLargest(int[] nums, int k) {
    
    
        int len = nums.length;
        int left = 0;
        int right = len - 1;

        // 转换一下,第 k 大元素的索引是 len - k
        int target = len - k;

        while (true) {
    
    
            int index = partition(nums, left, right);
            if (index == target) {
    
    
                return nums[index];
            } else if (index < target) {
    
    
                left = index + 1;
            } else {
    
    
                right = index - 1;
            }
        }
    }

    /**
     * 在数组 nums 的子区间 [left, right] 执行 partition 操作,返回 nums[left] 排序以后应该在的位置
     * 在遍历过程中保持循环不变量的语义
     * 1、[left + 1, j] < nums[left]
     * 2、(j, i] >= nums[left]
     *
     * @param nums
     * @param left
     * @param right
     * @return
     */
    public int partition(int[] nums, int left, int right) {
    
    
        int pivot = nums[left];
        int j = left;
        for (int i = left + 1; i <= right; i++) {
    
    
            if (nums[i] < pivot) {
    
    
                // 小于 pivot 的元素都被交换到前面
                j++;
                swap(nums, j, i);
            }
        }
        // 在之前遍历的过程中,满足 [left + 1, j] < pivot,并且 (j, i] >= pivot
        swap(nums, j, left);
        // 交换以后 [left, j - 1] < pivot, nums[j] = pivot, [j + 1, right] >= pivot
        return j;
    }

    private void swap(int[] nums, int index1, int index2) {
    
    
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }
}

knowledge of bit operations

Example:

一个整型数组里除了一个数字之外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字

Preliminary knowledge: XOR operation: If the two values ​​​​of a and b are not the same, the XOR result is 1. If the two values ​​of a and b are the same, the XOR result is 0.

The code is implemented as follows:

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    
    
    public int FindNumsAppearOnce(int [] array) {
    
    
        int sum = array[0];
        for(int i = 1;i < array.length;i++){
    
    
            sum ^= array[i];
        }
        return sum;
    }
}

space for time

Reducing time complexity by increasing space complexity is a common way to reduce time complexity. The relevant algorithm questions are as follows:

Two-dimensional array correlation

Must master code implementation

  • Implement an array that supports dynamic expansion
  • Realize an ordered array with a fixed size and support dynamic addition, deletion and modification operations
  • Merge two sorted arrays into one sorted array

Frequently Asked Algorithm Questions

reference

  • leetcode
  • "Sword Pointing to Offer"
  • Geek Time's "The Beauty of Data Structure and Algorithm" column

Guess you like

Origin blog.csdn.net/lichukuan/article/details/127019605
Recommended