返回
带着算法,上LeetCode挑战109道题(2019年8月上)!
前端
2023-11-23 15:36:03
自 2019-05-16 开始,jsliang 开始了 算法与数据结构 攻略(划水)之旅。为了帮助大家更高效地掌握算法与数据结构,并为您的编程面试做好准备,jsliang 每天会折腾一道及以上 LeetCode 题目,并将其解题思路记录成文章,发布到 GitHub 和 微信公众号 上。这里不一一累述,本次将8月上旬刷的109道题进行汇总,知识点为数组。
为了帮助您更好地理解和掌握这些知识点,我们按照以下顺序介绍:
- 基础概念
- 常见操作
- 常见算法
- 经典问题
基础概念
- 数组 :数组是一种数据结构,它由一组相同类型的数据元素组成。数组中的每个元素都有一个唯一的索引,索引从0开始。
- 一维数组 :一维数组是数组的一种特殊形式,它只有一行和多列。
- 二维数组 :二维数组是数组的另一种特殊形式,它有多行和多列。
- 三维数组 :三维数组是数组的第三种特殊形式,它有多行、多列和多层。
常见操作
-
创建数组 :可以使用以下两种方式创建数组:
- 使用数组字面量:
arr = [1, 2, 3, 4, 5]
* 使用数组构造函数:
arr = array.array('i', [1, 2, 3, 4, 5])
-
访问数组元素 :可以使用以下两种方式访问数组元素:
- 使用索引:
arr[0] # 输出 1
* 使用切片:
arr[1:3] # 输出 [2, 3]
- 修改数组元素 :可以使用以下方式修改数组元素:
arr[0] = 10
- 添加数组元素 :可以使用以下方式添加数组元素:
arr.append(6)
- 删除数组元素 :可以使用以下方式删除数组元素:
arr.pop()
常见算法
-
遍历数组 :遍历数组的常见算法有:
- 顺序遍历 :顺序遍历数组是最简单的一种遍历算法。它从数组的第一个元素开始,依次访问数组的每个元素,直到最后一个元素。
for i in range(len(arr)):
print(arr[i])
* **逆序遍历** :逆序遍历数组与顺序遍历数组相反,它是从数组的最后一个元素开始,依次访问数组的每个元素,直到第一个元素。
for i in range(len(arr) - 1, -1, -1):
print(arr[i])
* **二分查找** :二分查找是一种高效的查找算法,它适用于有序数组。二分查找算法首先将数组分成两半,然后比较目标值与数组中间元素的值。如果目标值小于中间元素的值,则继续在数组的前一半进行二分查找;如果目标值大于中间元素的值,则继续在数组的后一半进行二分查找。如此反复,直到找到目标值或确定目标值不存在于数组中。
def binary_search(arr, target):
left = 0
right = len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
-
排序数组 :排序数组的常见算法有:
- 冒泡排序 :冒泡排序是一种简单的排序算法,它通过不断地比较相邻元素,并将较大的元素向后移动,直到数组中的所有元素都按升序排列。
def bubble_sort(arr):
for i in range(len(arr) - 1):
for j in range(len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
* **选择排序** :选择排序也是一种简单的排序算法,它通过不断地找到数组中最小(或最大)的元素,并将其与数组的第一个元素交换,直到数组中的所有元素都按升序(或降序)排列。
def selection_sort(arr):
for i in range(len(arr) - 1):
min_index = i
for j in range(i + 1, len(arr)):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
* **插入排序** :插入排序是一种简单的排序算法,它通过不断地将一个元素插入到数组中适当的位置,直到数组中的所有元素都按升序排列。
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and key < arr[j]:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
* **归并排序** :归并排序是一种高效的排序算法,它通过不断地将数组分成两半,然后对每一半进行排序,最后合并两个有序的子数组,直到数组中的所有元素都按升序排列。
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left_half = merge_sort(arr[:mid])
right_half = merge_sort(arr[mid:])
return merge(left_half, right_half)
def merge(left_half, right_half):
i = 0
j = 0
merged = []
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
merged.append(left_half[i])
i += 1
else:
merged.append(right_half[j])
j += 1
while i < len(left_half):
merged.append(left_half[i])
i += 1
while j < len(right_half):
merged.append(right_half[j])
j += 1
return merged
* **快速排序** :快速排序是一种高效的排序算法,它通过不断地选择一个枢轴元素,然后将数组分成两部分,一部分包含所有小于枢轴元素的元素,另一部分包含所有大于枢轴元素的元素,最后对每一部分进行排序,直到数组中的所有元素都按升序排列。
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = []
right = []
for i in range(len(arr)):
if arr[i] < pivot:
left.append(arr[i])
elif arr[i] > pivot:
right.append(arr[i])
return quick_sort(left) + [pivot] + quick_sort(right)
经典问题
- 寻找最大子数组 :寻找最大子数组的问题是,给定一个数组,找到数组中连续的子数组,使得子数组的和最大。
def max_subarray(arr):
max_so_far = float('-inf')
max_ending_here = 0
for i in range(len(arr)):
max_ending_here = max_ending_here + arr[i]
if max_so_far < max_ending_here:
max_so_far = max_ending_here
if max