返回
每日算法&面试题,大厂特训二十八天——第十三天(数组)
后端
2023-09-19 21:20:02
前言
数组是一种常用的数据结构,它存储一组具有相同类型的数据元素,元素可以通过索引来访问。数组在编程中有着广泛的应用,如存储数据、处理数据、算法实现等。
数组的基本操作
查找
查找是数组中最基本的操作之一。它可以通过线性查找和二分查找两种方式实现。
- 线性查找:从数组的第一个元素开始,逐个元素比较,直到找到要查找的元素或者遍历完整个数组。
- 二分查找:将数组排序后,每次比较中间元素与要查找的元素,如果中间元素大于要查找的元素,则在左半部分继续查找;如果中间元素小于要查找的元素,则在右半部分继续查找。
排序
排序也是数组中常用的操作之一。它可以通过冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序等算法实现。
- 冒泡排序:从数组的第一个元素开始,逐个元素比较,如果前一个元素大于后一个元素,则交换这两个元素的位置。重复这个过程,直到数组中的所有元素都按升序排列。
- 选择排序:从数组的第一个元素开始,找到数组中最小(或最大)的元素,并将其与第一个元素交换位置。然后从第二个元素开始,重复这个过程,直到数组中的所有元素都按升序(或降序)排列。
- 插入排序:从数组的第二个元素开始,逐个元素比较,如果前一个元素大于后一个元素,则将后一个元素插入到前一个元素之前。重复这个过程,直到数组中的所有元素都按升序排列。
- 希尔排序:希尔排序是插入排序的改进版本。它将数组分成多个子数组,然后对每个子数组进行插入排序。这样可以提高排序的效率。
- 快速排序:快速排序是一种分而治之的排序算法。它将数组分成两个子数组,然后递归地对这两个子数组进行排序。这样可以将排序的时间复杂度降低到O(n log n)。
- 归并排序:归并排序也是一种分而治之的排序算法。它将数组分成两个子数组,然后递归地对这两个子数组进行排序。然后将两个有序的子数组合并成一个有序的数组。这样可以将排序的时间复杂度降低到O(n log n)。
插入
插入是数组中常用的操作之一。它可以通过两种方式实现:
- 在数组的末尾插入元素:在数组的末尾添加一个元素,然后将该元素的值赋给数组的最后一个元素。
- 在数组的中间插入元素:在数组的中间添加一个元素,然后将该元素的值赋给数组的中间元素,并将数组的右半部分的元素向后移动一位。
删除
删除是数组中常用的操作之一。它可以通过两种方式实现:
- 删除数组的最后一个元素:从数组的最后一个元素开始,将该元素的值赋给数组的倒数第二个元素,然后将数组的最后一个元素删除。
- 删除数组的中间元素:在数组的中间删除一个元素,然后将该元素的值赋给数组的中间元素,并将数组的右半部分的元素向前移动一位。
数组的经典算法
最大子数组和
最大子数组和是指数组中连续元素之和的最大值。它可以通过动态规划算法实现。
动态规划算法的思路如下:
- 定义一个数组dp,其中dp[i]表示以数组中的第i个元素结尾的连续子数组的最大和。
- 初始化dp数组。dp[0] = nums[0]。
- 对于数组中的每个元素nums[i],计算dp[i]。dp[i] = max(dp[i-1] + nums[i], nums[i])。
- 返回dp数组中的最大值。
最长公共子序列
最长公共子序列是指两个数组中的最长的公共子序列。它可以通过动态规划算法实现。
动态规划算法的思路如下:
- 定义一个二维数组dp,其中dp[i][j]表示数组A的前i个元素和数组B的前j个元素的最长公共子序列的长度。
- 初始化dp数组。dp[0][0] = 0。
- 对于数组A中的每个元素a[i],对于数组B中的每个元素b[j],计算dp[i][j]。dp[i][j] = max(dp[i-1][j], dp[i][j-1], dp[i-1][j-1] + (a[i] == b[j] ? 1 : 0))。
- 返回dp数组中的最大值。
大厂的面试题
阿里巴巴
- 给定一个数组nums,找到数组中所有连续子数组的最大和。
- 给定两个数组A和B,找到这两个数组的最长公共子序列。
- 给定一个数组nums,找到数组中所有连续子数组的最小和。
腾讯
- 给定一个数组nums,找到数组中所有连续子数组的平均值。
- 给定两个数组A和B,找到这两个数组的最长公共子串。
- 给定一个数组nums,找到数组中所有连续子数组的乘积。
字节跳动
- 给定一个数组nums,找到数组中所有连续子数组的方差。
- 给定两个数组A和B,找到这两个数组的最长公共子序列的长度。
- 给定一个数组nums,找到数组中所有连续子数组的众数。
结语
数组是一种常用的数据结构,它在编程中有着广泛的应用。本文介绍了数组的基本操作、经典算法和大厂的面试题,希望能够帮助读者更好地理解和应用数组。