当前位置: 首页 > news >正文

数组

数组

数组

引文:数组看起来简单基础,但是很多人没有理解这个数据结构的精髓。带着为什么数组要从0开始编号,而不是从1开始的问题,进入主题。

数组如何实现随机访问

  • 数组是一种线性数据结构,用连续的存储空间存储相同类型的数据

  • 线性表:数组、链表、队列、栈

     

    array1
    array1

     

  • 非线性表: 树、图

     

    array2
    array2

     

  1. 数组如何实现下标随机访问?

     

    array3
    array3

     

  • 一维数组寻址公式:a[i]_address = base_address + i*data_type_size
  1. 纠正数组和链表的错误认识。数组的查找操作时间复杂度并不是O(1)。即便是有序数组,用二分查找,时间复杂度也是O(logn) . 正确表述:数组支持随机访问,根据下标随即访问的时间复杂度为O(1)。

低效的插入和删除

  1. 插入:最好O(1)【尾插】 最坏O(n) 【头插】 平均O(n)

  2. 另一种插入: 数组若无序,插入新的元素时,可以将第k个位置的元素移动到数组末尾,把新的元素插入到第k个位置,此处复杂度为 O(1)

  3. 删除:最好O(1)【尾删】 最坏O(n) 【头删】 平均O(n)

  4. 多次删除集中在一起,提高效率

    记录下已经被删除的数据,每次的删除操作并不是搬移数据,只是记录数据已经被删除,当数组没有更多的存储空间时,再触发一次真正的删除操作。即JVM标记清除垃圾回收算法。

数组的访问越界问题

例子:

int main(int argc, char* argv[]){
    int i = 0;
    int arr[3] = {0};
    for(; i<=3; i++){
        arr[i] = 0;
        printf("hello world\n");
    }
    return 0;
}
  • 此例在《C陷阱与缺陷》出现过:如果用来编译这段程序的编译器按照内存地址递减的方式给变量分配内存,那么内存中的 i 将会被置为0,则为死循环永远出不去。 【注】64位操作系统下,编译器默认会8字节对齐。 类型同为int

容器能否完全替代数组?

相比于数字,java中的ArrayList封装了数组的很多操作,并支持动态扩容。一旦超过存储容量,扩容时比较消耗内存,因为涉及到内存申请和数据搬移。

数组适合的场景:

  1. Java ArrayList 的使用涉及装箱和拆箱,有一定的性能损耗,如果特别关注性能,可以考虑数组。
  2. 若数据大小事先已知,并且涉及的数据操作非常简单,可以使用数组。
  3. 表示多维数组的时候,数组往往更加直观。
  4. 业务开发容器即可,底层开发,如网络框架,性能优化。选择数组

解答开篇问题

  • 从偏移(offset)角度理解 a[0] 0 为偏移量,如果从1开始计数,会多出 k-1 。增加了一次减法运算,增加CPU负担。为什么循环要写成for(int i = 0;i<3;i++) 而不是for(int i = 0 ;i<=2;i++)。第一个直接就可以算出$3-0 = 3$ 有三个数据,而后者 $2-0+1$个数据,多出1个加法运算,很恼火。
  • 也有一定的历史原因。

课后练习

三数之和

  • 题目描述:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 *a,b,c ,*使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    **注意:**答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    
  • Ans:

     1 public class Sum {
     2     public List<List<Integer>> threeSum(int[] nums){
     3         List<List<Integer>> res = new ArrayList<>();
     4         Arrays.sort(nums);
     5         for (int i = 0; i < nums.length - 2; i++){
     6             if(i > 0 && nums[i] == nums[i-1]) continue;
     7             int low = i + 1, high = nums.length - 1, sum = 0 - nums[i];
     8             while (low < high) {
     9                 if(nums[low] + nums[high] == sum){
    10                     res.add(Arrays.asList(nums[i],nums[low],nums[high]));
    11                     while(low < high && nums[low] == nums[low+1]) low++;
    12                     while(low < high && nums[high] == nums[high-1]) high--;
    13                     low++;
    14                     high--;
    15                 }else if (nums[low] + nums[high] < sum) {
    16                     low++;
    17                 }else{
    18                     high--;
    19                 }
    20             }
    21         }
    22         return res;
    23     }
    24 }

     

转载于:https://www.cnblogs.com/jiaweixie/p/10382983.html

相关文章:

  • golang 发送GET和POST示例
  • 监听器
  • 用Hexo搭建属于自己的Blog
  • ipcs命令详解
  • 多态
  • 个人站点的日期查询
  • 2017-2018年度Scrum现状报告发布
  • 我们的春节--2019
  • BZOJ 1412 狼和羊的故事
  • LeetCode29.两数相除 JavaScript
  • vim命令模式下光标移动+查找
  • Fastjson的基本使用方法大全
  • 面孔相册按脸给照片分类 这是靠小米人脸检测技术实现的
  • 数据结构java版之冒泡排序及优化
  • 洛谷1474货币系统——小心重复的完全背包
  • Cumulo 的 ClojureScript 模块已经成型
  • Docker: 容器互访的三种方式
  • express.js的介绍及使用
  • IDEA常用插件整理
  • laravel with 查询列表限制条数
  • Netty 4.1 源代码学习:线程模型
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • storm drpc实例
  • Vue 2.3、2.4 知识点小结
  • 微信小程序--------语音识别(前端自己也能玩)
  • 写给高年级小学生看的《Bash 指南》
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (9)目标检测_SSD的原理
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (第61天)多租户架构(CDB/PDB)
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (三) diretfbrc详解
  • (三)elasticsearch 源码之启动流程分析
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)基于IDEA的JAVA基础1
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转)Linux整合apache和tomcat构建Web服务器
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .NET Core中的去虚
  • .NET 解决重复提交问题
  • .net 流——流的类型体系简单介绍
  • @Autowired和@Resource的区别
  • @requestBody写与不写的情况
  • [14]内置对象
  • [android学习笔记]学习jni编程
  • [Angular] 笔记 21:@ViewChild
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据