首页 > 编程语言 > 详细

数据结构-数组

时间:2020-05-25 00:25:06      阅读:60      评论:0      收藏:0      [点我收藏+]

数组(array)

数组

数组是一种基本的数据结构,用于按顺序存储元素的集合。但是元素可以随机存取,因为数组中的每个元素都可以通过数组索引来识别。

数组可以有一个或多个维度。这里我们从一维数组开始,它也被称为线性数组。如下所示:

技术分享图片

在上面的例子中,数组 A 中有 6 个元素。也就是说,A 的长度是 6 。我们可以使用 A[0] 来表示数组中的第一个元素。因此,A[0] = 6 。类似地,A[1] = 3,A[2] = 8,依此类推。此外,数组一旦定义后,大小不能更改。

// golang中的数组

// 声明一个float32类型且长度为10数组
var balance [10] float32
// 初始化已声明数组
balance = [10]float32{1, 2, 3, 4}
balance[0] = 2

// 声明并定义一个数组
var balance = [10]float32{1, 2, 3, 4}

// 根据元素个数,设置数组长度
var balance = [...]float32{1, 2, 3, 4}

// 只能在函数内使用这种格式
balance := [...]float32{1, 2, 3, 4}

// 遍历数组
func main() {
	var a = [...]string{"北京", "上海", "深圳"}
	// 方法1:for循环遍历
	for i := 0; i < len(a); i++ {
		fmt.Println(a[i])
	}

	// 方法2:for range遍历
	for index, value := range a {
		fmt.Println(index, value)
	}

动态数组

数组具有固定的容量,我们需要在初始化时指定数组的大小。有时它会非常不方便并可能造成浪费。

因此,大多数编程语言都提供内置的动态数组,它仍然是一个随机存取的列表数据结构,但大小可变

在Golang中为切片(slice),它非常灵活,支持自动扩容。

// 声明切片
var slice []float32
// 初始化切片
slice = []float32{1, 2, 3, 4}

// 声明+初始化
var slice = []float32{1, 2, 3, 4}

// 只能在函数内使用这种格式
slice := []float32{1, 2, 3, 4}

// 用make来创建切片 ---> make([]T, length, capacity)
var slice []float32 = make([]float32, 5, 10)
slice := make([]float64, 5, 10)

// 常用函数  
len(slice) // 长度
cap(slice) // 容量
append(slice,要添加元素) 
copy(slice1,slice) // slice ---> slice1

下面是关于数组(二维数组)的三个案例**:

1. 寻找数组的中心索引

给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和

如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

示例 1:

输入: 
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释: 
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。

示例 2:

输入: 
nums = [1, 2, 3]
输出: -1
解释: 
数组中不存在满足此条件的中心索引。

说明:

  • nums 的长度范围为 [0, 10000]
  • 任何一个 nums[i] 将会是一个范围在 [-1000, 1000]的整数。
func pivotIndex(nums []int) int {
    
	sum := 0
	leftSum := 0

	for _,i := range nums {
		sum += i
	}

	for k,v := range nums {
		if leftSum == sum - v - leftSum {
			return k
		}
		leftSum += v
	}

	return -1
}

2. 至少是其他数字两倍的最大数

在一个给定的数组nums中,总是存在一个最大元素 。

查找数组中的最大元素是否至少是数组中每个其他数字的两倍。

如果是,则返回最大元素的索引,否则返回-1。

示例 1:

输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.

示例 2:

输入: nums = [1, 2, 3, 4]
输出: -1
解释: 4没有超过3的两倍大, 所以我们返回 -1.

提示:

  1. nums 的长度范围在[1, 50].
  2. 每个 nums[i] 的整数范围在 [0, 100].
func dominantIndex(nums []int) int {
    
	index := -1
	if len(nums) == 0 { // 数组只有一个数的情况
		return index
	}
	
	//求出最大值
	max := nums[0]
	for i, v := range nums {
		if v >= max {
			max = v
			index = i
		}
	}

	for i, _ := range nums {
		if i == index{  // 忽略最大值
			continue
		}
		if nums[i]*2 > max {
			return -1
		}
	}
	return index
}

3. 加一

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。

示例 2:

输出: [4,3,2,2]
解释: 输入数组表示数字 4321。

解:

func plusOne(digits []int) []int {
    /*
    	考察进位为问题
     */
	for i := len(digits) - 1; i >= 0; i-- {
        // 数组最末元素如果不是9,直接加1返回
        // 否则该元素置零,前一项元素加1,以此类推
		if digits[i] < 9 {
			digits[i]++
			return digits
		} else {
			digits[i] = 0
		}
	}
    // 以上操作都没有返回数组,则证明数组第一个元素也需要进位
    // 合并数组
	return append([]int{1}, digits...)
}

二维数组

类似于一维数组,二维数组也是由元素的序列组成。但是这些元素可以排列在矩形网格中而不是直线上。

二维数组是最简单的多维数组,二维数组本质上是由一维数组组成的。二维数组定义方式如下:

var arrayName [ x ][ y ] variable_type

variable_type 为 Go 语言的数据类型,arrayName 为数组名,二维数组可认为是一个表格,x 为行,y 为列,下图演示了一个二维数组 a 为三行四列

技术分享图片

二维数组中的元素可通过 a[i][j]来访问。

练习如下:

1. 对角线遍历

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

示例:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

输出:  [1,2,4,7,5,3,6,8,9]

含义:技术分享图片

说明:

  1. 给定矩阵中的元素总数不会超过 100000 。
func findDiagonalOrder(matrix [][]int) []int {
    
/*
看作一个小球在矩形框格中碰壁移动的情形,共移动i*j次
首先根据行与列之和 i+j 的奇偶确定移动的方向,奇数向右上,偶数向左下。
每次行走方向又有三种边界的情况
1.上边界或者下边界碰壁后向右走,即j+1
2.左边界或者右边界碰壁后向下走,即i+1
3.去他情况:右上遍历:i-1,j+1;左下遍历:i+1;j-1
 */
    
    var result []int      // 返回的一维数组
	if len(matrix) == 0 {      // 二维数组为空
		return result
	}
	
    rowLen, columnLen := len(matrix), len(matrix[0]) // 二维数组行、列数
	i := 0 // 当前所在行
	j := 0 // 当前所在列

	for k := 0; k < rowLen*columnLen; k++ {
		result = append(result, matrix[i][j])

		// 行+列 和为偶数时 向右上方遍历,此后分为三种情况
		if (i+j)%2 == 0 {
			if j == columnLen-1 { // 撞右墙往下走
				i++
			} else if i == 0 { // 撞最上端墙往右走
				j++
			} else { // 没撞墙斜着走
				j++
				i--
			}
		// 行+列 和为奇数时 向左下方遍历,此后分为三种情况
		} else {
			if i == rowLen-1 { // 撞下墙往右走
				j++
			} else if j == 0 { // 撞左墙往右走
				i++
			} else { // 没撞墙斜着走
				j--
				i++
			}
		}
	}
	return result
}

2. 螺旋矩阵

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

示例 2:

[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

解:

func spiralOrder(matrix [][]int) []int {
	
	/*
	   分为四种情况,遍历到左边界,下边界,右边界,上边界
	*/
	
	var result []int      // 返回的一维数组
	if len(matrix) == 0 { // 二维数组为空
		return result
	}

	// 上边界,下边界,左边界,右边界
	top, bottom, left, right := 0, len(matrix)-1, 0, len(matrix[0])-1
	// 当前位置坐标
	i, j := 0, 0
	// 运动方向。1表示向右,2:向下,3:向左。4:向上
	dir := 1

	for top <= bottom && left <= right {
		result = append(result, matrix[i][j])

		switch dir {
		// 1,2,3,4:右,下,左,上
		case 1:
			if j == right { // 如果到了右端,向下移动1,且上边界+1
				dir = 2
				i++
				top++
				continue
			}
			j++ // 向右移动1
		case 2:
			if i == bottom { // 如果到了下端,向左移动1,且右边界-1
				dir = 3
				j--
				right--
				continue
			}
			i++ // 向下移动1
		case 3:
			if j == left { // 如果到了左端,向上移动1,且下边界-1
				dir = 4
				i--
				bottom--
				continue
			}
			j-- // 向左移动1
		case 4:
			if i == top { // 如果到了上端,向左移动1,且左边界+1
				dir = 1
				j++
				left++
				continue
			}
			i-- // 向上移动1
		}
	}
	return result
}

3. 杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

附:在杨辉三角中,每个数是它左上方和右上方的数的和

示例:

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

解:

func generate(numRows int) [][]int {
	
    // 容量(行)为 numRows
	nums := make([][]int,numRows)
	for i:=0;i<numRows;i++ {
		// 每一行的容量为 i+1
		nums[i] = make([]int,i+1)
		// 每行第一个元素为 1
		nums[i][0] = 1
		// 中间元素运算
		for j:=1;j<len(nums[i])-1;j++ {
			nums[i][j] = nums[i-1][j-1] + nums[i-1][j]
		}
		// 每行最后一个元素为1
		nums[i][i] = 1
	}
	return nums
}

数据结构-数组

原文:https://www.cnblogs.com/newbase/p/12953679.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!