数组
集合、列表和数组
集合:一个或多个元素构成的整体,里面的元素类型不一定相同,且是无序的
列表:又称线性列表,有顺序且长度是可变的,没有索引有顺序,可以增删改
数组:列表的实现方式之一,数组有索引,数组在内存中的存储是连续的,列表则不一定
Think&Code
寻找数组的中心索引
给你一个整数数组 nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
示例:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
提示:
- 1 <= nums.length <= 104
- -1000 <= nums[i] <= 1000
思路
- 获取数组里所有数字的和'sum',然后遍历数组,使得数组里数字逐个相加获得'leftSum',同时'sum'减去'leftSum'和当前索引的值就获得了数组右边的值,如果与'leftSum'相等则返回当前索引
实现
public static int pivotIndex(int[] nums) {
int sum = 0,leftSum = 0;
for (int num : nums) { // 可以用Stream API写成 sum = Arrays.stream(nums).sum();
sum+=num;
}
for (int i=0; i<nums.length; i++){
if (leftSum == (sum-leftSum-nums[i])) { // sum减去leftSum和当前索引的值比较是否相等
return i;
}
leftSum += nums[i];
}
return -1;
}
搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例1:
输入: nums = [1,3,5,6], target = 5 输出: 2
示例2:
输入: nums = [1,3,5,6], target = 2 输出: 1
示例3:
输入: nums = [1,3,5,6], target = 7 输出: 4
提示:
- 1 <= nums.length <= 104
- -104 <= nums[i] <= 104
- nums 为 无重复元素 的 升序 排列数组
- -104 <= target <= 104
思路
- 遍历数组中的每个元素,如果元素大于等于目标值,返回当前的索引(缺点:数据较多时,不够高效)
- 使用二分查找进行优化,定义两个指针并取数组的中间值,如果中间值等于目标值直接返回,小于的话右指针等于中间值减一,反之左指针等于中间值加一,不断循环取中间值,直到左指针大于右指针最后返回左指针。
实现
public int searchInsert(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= target) return i;
}
return nums.length;
}
实现2(二分查找)
public static int searchInsert2(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 为了防止整形溢出
if (target == nums[mid]) {
return mid;
} else if (target > nums[mid]) {
left = mid + 1;
} else if (target < nums[mid]) {
right = mid - 1;
}
}
return left;
}
合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
提示:
- 1 <= intervals.length <= 104
- intervals[i].length == 2
- 0 <= starti <= endi <= 104
思路
- 首先对二维数组中的数组按照第一个元素升序排序,判断数组的第二个元素是否大于等于下一个数组的第一个元素,直到不满足条件然后加入一个列表里面,遍历结束之后将列表转为数组并返回
实现
public static int[][] merge(int[][] intervals) {
if (intervals.length == 0) return intervals;
Arrays.sort(intervals,(a,b) -> a[0] - b[0]); // 对二维数组进行排序
List<int[]> list = new ArrayList<>();
int[] flag = intervals[0];
for (int i = 1; i < intervals.length; i++) {
if (flag[1] >= intervals[i][0]) {
flag[1] = Math.max(flag[1], intervals[i][1]);
}else {
list.add(flag);
flag = intervals[i];
}
}
list.add(flag);
return list.toArray(new int[list.size()][2]);
}
二维数组
二维数组是一种结构较为特殊的数组,只是将数组中的每个元素变成了一维数组。
Think&Code
旋转矩阵
给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?
示例1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例2:
给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
思路
- 使用辅助数组,对原数组的每一行进行遍历,每一行进行单独的旋转
- 原地旋转,对数组的一半进行遍历(旋转之后另一半会随着旋转)
实现
public static void rotate(int[][] matrix) {
int len = matrix.length;
int[][] newArray = new int[len][len];
int max = len - 1;
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
newArray[j][max-i] = matrix[i][j];
}
}
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
matrix[i][j] = newArray[i][j];
}
}
}
实现2(原地旋转)
public static void rotate2(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n/2; i++) {
for (int j = 0; j < n/2; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n-j-1][i];
matrix[n-j-1][i] = matrix[n-i-1][n-j-1];
matrix[n-i-1][n-j-1] = matrix[j][n-i-1];
matrix[j][n-i-1] = temp;
}
}
}
零矩阵
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
示例:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
思路
- 遍历整个二维数组,碰到0之后用户两个布尔数组记录下横纵坐标(0为true),再遍历一次根据两个数组的布尔值进行变0的操作
实现
public static void setZeroes1(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean[] row = new boolean[m];
boolean[] col = new boolean[n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (row[i] || col[j] == true) {
matrix[i][j] = 0;
}
}
}
}
标签:matrix,nums,int,++,二维,intervals,数组,数据结构
From: https://www.cnblogs.com/akaazheng/p/16737142.html