【数据结构与算法】力扣刷题记之 稀疏数组

2024-02-09 19:12

本文主要是介绍【数据结构与算法】力扣刷题记之 稀疏数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 🎉🎉欢迎光临🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟特别推荐给大家我的最新专栏《数据结构与算法:初学者入门指南》📘📘

本专栏纯属为爱发电永久免费!!!

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net/

目录

深入理解稀疏数组

稀疏数组:概念与应用场景

第一节:稀疏数组的基础概念及应用场景

第二节:实现稀疏数组的转换与应用

实现稀疏数组的转换

通过稀疏数组恢复出原始的普通数组。具体恢复过程如下:

稀疏数组的恢复与应用

探讨稀疏数组在题目以及实际开发中的应用场景

题目描述

稀疏数组压缩与恢复算法

思路分析


深入理解稀疏数组

稀疏数组:概念与应用场景

第一节:稀疏数组的基础概念及应用场景

稀疏数组是一种特殊的数组数据结构,其特点是大部分元素为同一值或者为0。在实际应用中,稀疏数组常常被用来存储那些绝大多数元素为0的二维数据,如图像、矩阵等。一个典型的应用场景是图像处理中的位图压缩。

在不使用稀疏数组的情况下,如果直接用二维数组来表示稀疏性很高的数据结构,会导致大量的存储空间浪费和性能损耗。例如,对于一个大规模的稀疏矩阵,如果每个元素都占用存储空间,将会占用大量的存储空间。而且在处理这样的数据结构时,需要额外的时间复杂度来遍历和操作大量的0值元素。

引入稀疏数组可以有效解决上述问题。通过稀疏数组的存储方式,我们可以只存储非零元素及其位置信息,从而大大减少存储空间的占用。同时,在对稀疏数组进行操作时,可以极大地提高程序的运行效率。

第二节:实现稀疏数组的转换与应用

实现稀疏数组的转换

下面是一个简单的示例代码,用于将普通的二维数组转换为稀疏数组:

假设我们有一个普通的二维数组如下:

普通数组:

 [[0, 0, 0, 0, 0],
 [0, 5, 0, 0, 0],
 [0, 0, 8, 0, 0],
 [0, 0, 0, 0, 0]]

我们希望将这个普通数组转换为稀疏数组。转换过程中,我们需要记录非零元素的位置和数值,并在稀疏数组的第一行记录原始数组的行数、列数和非零元素个数。具体转换过程如下:

遍历原始数组,记录非零元素及其位置:

非零元素 (1, 1) 值为 5
非零元素 (2, 2) 值为 8
 

将记录的非零元素及其位置转换为稀疏数组:

稀疏数组:

[[4, 5, 2],  # 第一行记录原始数组的行数、列数和非零元素个数
 [1, 1, 5],  # 非零元素 (1, 1) 值为 5
 [2, 2, 8]]  # 非零元素 (2, 2) 值为 8

通过稀疏数组恢复出原始的普通数组。具体恢复过程如下:

  1. 根据稀疏数组的第一行信息创建一个全为0的普通数组。

  2. 遍历稀疏数组中的非零元素,根据其位置信息将对应的值填入新建的普通数组中。

def convert_to_sparse_array(arr):sparse_arr = []rows, cols = len(arr), len(arr[0])count = 0# 遍历原始数组,记录非零元素及其位置for i in range(rows):for j in range(cols):if arr[i][j] != 0:sparse_arr.append([i, j, arr[i][j]])count += 1# 在稀疏数组的第一行记录原始数组的行数、列数和非零元素个数sparse_arr.insert(0, [rows, cols, count])return sparse_arr

稀疏数组的恢复与应用

除了将普通数组转换为稀疏数组,我们还需要实现将稀疏数组恢复为普通数组的功能。下面是一个简单的示例代码:

def restore_from_sparse_array(sparse_arr):rows, cols, count = sparse_arr[0]restored_arr = [[0 for _ in range(cols)] for _ in range(rows)]for i in range(1, count+1):row, col, val = sparse_arr[i]restored_arr[row][col] = valreturn restored_arr

探讨稀疏数组在题目以及实际开发中的应用场景

稀疏数组在实际项目中有许多应用场景,如图像处理、文本搜索、语音识别等。其中,最常见的应用场景是图像处理中的位图压缩。

在算法题领域中,稀疏数组也有广泛的应用。例如力扣(LeetCode)中的73题矩阵置零,就可以使用稀疏数组来进行优化,减少存储空间的占用。

力扣(LeetCode)73题矩阵置零的原题如下:

题目描述

给定一个m x n的矩阵,如果一个元素为0,则将其所在行和列的所有元素都设为0。请使用原地算法。

示例 1:

输入:
[[1,1,1],[1,0,1],[1,1,1]
]
输出:
[[1,0,1],[0,0,0],[1,0,1]
]

示例 2:

输入:
[[0,1,2,0],[3,4,5,2],[1,3,1,5]
]
输出:
[[0,0,0,0],[0,4,5,0],[0,3,1,0]
]
// 稀疏数组压缩算法示例
void compress(int** ori_arr, int row, int col, int* arr_len, int*** com_arr) {int count = 0;for (int i = 0; i < row; ++i) {for (int j = 0; j < col; ++j) {if (ori_arr[i][j] != 0) {++count;}}}*com_arr = malloc((count + 1) * sizeof(int*));(*com_arr)[0] = malloc(3 * sizeof(int));(*com_arr)[0][0] = row;(*com_arr)[0][1] = col;(*com_arr)[0][2] = count;int index = 1;for (int i = 0; i < row; ++i) {for (int j = 0; j < col; ++j) {if (ori_arr[i][j] != 0) {(*com_arr)[index] = malloc(3 * sizeof(int));(*com_arr)[index][0] = i;(*com_arr)[index][1] = j;(*com_arr)[index][2] = ori_arr[i][j];++index;}}}*arr_len = count + 1;
}// 稀疏数组恢复算法示例
void restore(int** ori_arr, int* arr_len, int*** com_arr) {int row = (*com_arr)[0][0];int col = (*com_arr)[0][1];for (int i = 0; i < row; ++i) {for (int j = 0; j < col; ++j) {ori_arr[i][j] = 0;}}for (int i = 1; i < *arr_len; ++i) {int x = (*com_arr)[i][0];int y = (*com_arr)[i][1];int val = (*com_arr)[i][2];ori_arr[x][y] = val;}
}

稀疏数组压缩与恢复算法

思路分析

稀疏数组的压缩算法可以将数组进行压缩,从而减少存储空间的占用。具体来说,稀疏数组的压缩算法会按照一定的规则,将非零元素的值及其所在的位置信息记录下来,并将其存储为三元组的形式。

以下是稀疏数组的压缩算法思路:

  1. 遍历原始数组,统计非零元素的个数count。
  2. 创建一个新的二维数组com_arr,大小为(count + 1) * 3,其中count + 1表示非零元素的个数加上一行用于记录原始数组的行数、列数和非零元素的总个数。
  3. 将原始数组的行数、列数和非零元素的总个数分别存储在com_arr的第一行。
  4. 遍历原始数组,将非零元素的行、列和值存储在com_arr的后续行中。
  5. 返回压缩后的数组com_arr和非零元素的个数count + 1。

稀疏数组的恢复算法则是根据压缩时的规则将压缩后的数据恢复为原始的数组数据。

以下是稀疏数组的恢复算法思路:

  1. 根据压缩后的数组com_arr的第一行,获取原始数组的行数row、列数col。
  2. 创建一个新的二维数组ori_arr,大小为row * col,并将其所有元素初始化为0。
  3. 遍历com_arr的后续行,将非零元素的值和对应的位置信息恢复到ori_arr中。
  4. 返回恢复后的数组ori_arr。

 

这篇关于【数据结构与算法】力扣刷题记之 稀疏数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695067

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个