> 文档中心 > 涤生校招算法系列5:数组基本操作必掌握

涤生校招算法系列5:数组基本操作必掌握

     校招不同于社招,不管是科班的大数据/计算机相关类专业的,还是其他专业转行大数据的小伙伴。同样大数据校招面试也是更看重基础(尤其是中大厂),校招不仅需要掌握大数据相关技术,还需要掌握一些基础知识(如计算机基础,算法数据结构),校招面试内容杂而多,如何系统化备战?

     桐哥,壮哥,21年毕业研究生,目前在职快手,米哈游。俩人是校招收割机,校招拿到了美团,字节,快手,京东,滴滴,携程,小米,vivo,米哈游,好未来,小红书,garena,贝壳找房,招行,兴业银行等多家大中厂大数据校招Offer。现在趁着热乎劲,亲自带大家进行大数据校招学习。结合自身校招经历,亲自系列化总结大数据校招知识,剖析核心知识,系统化带大家备战校招,规划学习,考勤打卡。懒人模式--你只需要负责完成每天每周打卡学习即可,而不需要担心应该学习什么?

万里长征第一步,本周我们的小伙伴们在老师的带领下已经学习完了整个数组系列。

1. 刷题必需知识储备

1.掌握主流编程语言之一:C语言,C++,JAVA,或者Python等(建议使用java)2.数组相关基础概念知识

2.数组基础知识概述

        数组,作为互联网行业校招算法考察的重点,其基本操作是必须掌握的。数组的特性是可以通过下标访问元素,直接定义的数组需要指定数组长度且定义后长度不能修改,本文目的主要帮助大家熟悉数组的操作,为较基础的题目。

         数组是在程序设计中,把具有相同类型的若干元素按有序的形式组织起来的一种形式。 数组 (Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素。

         数组作为线性表的实现方式之一,数组中的元素在内存中是连续存储的,且每个元素占相同大小的内存。

        注意:在不同的编程语言中,数组的实现方式具有一定差别。比如 C++ 和 Java 中,数组中的元素类型必须保持一致,而 Python 中则可以不同。相比之下,Python 中的数组(称为 list)具有更多的高级功能。

 在笔面试过程中,一般需要重点掌握一维数组和二维数组的使用。

2.1一维数组

   数组是存储在连续内存空间上的相同类型类型的集合,其通过索引(脚标)快速访问每个元素的值。在大多数编程语言中,脚标(索引)从 0 算起。数组是由相同类型的数据元素构成的有限集合,一维数组可以看作一个线性表。一维数组的元素有1个下标。

划重点咯:

数组下标都是从0开始的。数组在内存空间的地址是连续的。删除或者增添元素时难免要移动其他元素的地址。

2.2二维数组

二维数组也可以看作一个线性表X=(X0,X1,X2,…,Xn-1),只不过每一个数据元素Xi也是一个线性表。

二维数组的元素中有 2 个下标。如int a[3][2]的元素在内存中按行连续放置:

但无论是一维还是二维,数组是在内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。

2.3 数组使用及优缺点

优点

1.按照索引查询元素速度快2.按照索引遍历数组方便

缺点

1.数组的大小固定后就无法扩容了2.数组只能存储一种类型的数据3.添加,删除的操作慢,因为要移动其他的元素。

数组适用频繁查询,对存储空间要求不大,很少增加和删除的情况。这里的适用场景需要可以记忆一下,后续练习中会有体会哈。

3.数组基础题必掌握

        数组的特性是可以通过下标访问元素,直接定义的数组需要指定数组长度且定义后长度不能修改,本节题目主要帮助大家熟悉数组的操作,为较基础的题目

1.加一(力扣66)

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:输入:digits = [1,2,3]输出:[1,2,4]解释:输入数组表示数字 123。
思路:本题以数组的形式给定一个数字,数组中每个元素只存储单个数字。所以加1的操作自然是从数组的最后一位开始操作。主要考察数组的基本操作。
1.对数组最后一位开始加1操作;2.需要判断是否进位操作-> 加1大于10则进位1,当前下标为0;加1小于10则不需要进位,直接+1即可;3.继续对高位下标进行第2步操作

实现

import java.util.Arrays;public class AddOne {    public static void main(String[] args) { int[] nums = {1,2,3}; System.out.println(Arrays.toString(plusOne(nums)));    }    public static int[] plusOne(int[] digits) {      for (int i = digits.length - 1; i > -1; i--) {   //最后一个数字加一取余,如果相加小于10则不变,如果等于10则该位被赋值为0   //从第二次循环到这里时,加一就意味着加的是前一位的进位   digits[i] = (digits[i] + 1) % 10;   //如果当前位加一取余之后不等于0的话,就意味着没有产生进位所以直接可以返回   if (digits[i] != 0)return digits;      }      //如果前面的代码没有返回,一直执行到了这一步,意味着输入数组的最高位也需要进位      //那么直接new一个比原来数组长度加一的新数组,然后将下标0的位置赋值为1      digits = new int[digits.length + 1];      digits[0] = 1;      return digits;    }} 

2.最大连续1的个数(力扣485)

给定一个二进制数组 nums , 计算其中最大连续 1 的个数。

示例 1:输入:nums = [1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.

思路:

同样考察数组的基本操作,对数组中连续的1进行计数,并取最大的连续值。

实现

public class findMaxOne {    public static void main(String[] args) { int[] nums={1,1,0,1,1,1};  //{1,1,0,1,1,1,2,1,1,1,1,1} System.out.println(findMaxOne(nums));    }    public static int findMaxOne(int[] nums) { int max = 0; int s = 0; for(int i = 0 ; i < nums.length ;i++){     if(nums[i] == 1){  //如果取出的值等于1 就 ++  s++;  //求最大计数值  max = Math.max(max, s);     }else{  //遇到不是1就清零0 开始记数  s = 0;     } } return max;    }}

3.杨辉三角(力扣118)

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。示例 1:输入: numRows = 5输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

杨辉三角其实就是高中学过的二项式系数的性质,规律如下图。

思路:使用两个for循环遍历数组元素,在外层循环中初始化每一个第二层数组的大小。在内层循环中,先将两侧的数组元素赋值为1,其他数值通过公式计算,然后输出数组元素。

实现

以下代码中包含两种方法,第一种是基本数组处理的方法,第二种递归方法较为推荐解决该类问题。

package array;import java.util.Scanner;public class YangHui {    public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int sc=scanner.nextInt(); System.out.println(yanhui_arr(sc)); //采用递归方法/* for (int i = 1; i <= 6; i++) {     for (int j = 1; j <= i; j++) {  System.out.print(recursion(i, j) + " ");     }     System.out.println(""); }*/    }    //数组循环方法    public static String yanhui_arr(int sc){ //初始一个二维数组 int[][] nums=new int [sc][sc]; for (int i = 0; i < sc; i++) {     // 格式化输出(第一个数前面),如"%20s"代表空20个空格     System.out.format("%" + (sc - i) * 2 + "s", "");     for (int j = 0; j <= i; j++) {//i代表纵坐标,j代表横坐标  if (j == 0 || j == i) {// ||或者,即满足任意一个      //每一行第一个数和最后一个数都为1      nums[i][j] = 1;  } else {      //杨辉三角的值等于其上一层两个值之和;a[i][j]代表数组坐标的位置,i代表纵坐标,j代表横坐标      //nums[i - 1][j - 1]代表上一层两个值中的前一个;nums[i - 1][j]代表上一层两个值中的后一个,注:索引都是从0开始      nums[i][j] = nums[i - 1][j - 1] + nums[i - 1][j];  }  //分别输出i和j的值,i的值输出按原样输出,对于j就是按3位的固定位宽输出(不足4位,在前面补空格;超过4位,按实际位数输出),  //即输出宽度为4,不够的用空格填充,比如你的数本来宽2,就加2个空格;本来宽3,就加1个空格。  System.out.format("%4d", nums[i][j]);     }     System.out.println();//换行 } return "";    }    //递归    public static int recursion(int m, int n) { int ret = 0; // if ((n == 1) || (m == n)) {     ret = 1; }else{     //重点理解公式   f(n)=f(n-1)+f(n-2)     ret=recursion(m-1,n)+recursion(m-1,n-1); } return ret;    }}