LeetCode

数组和字符串

LeetCode 724(寻找数组的中心下标)

(LeetCode 1991(找到数组的中间位置)相同)

题目描述:

给你一个整数数组 nums ,请计算数组的 中心下标

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

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

示例 1:

1
2
3
4
5
6
输入: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 ,二者相等。

示例 2:

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

示例 3:

1
2
3
4
5
6
输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。

提示:

  • 1 <= nums.length <= 104
  • -1000 <= nums[i] <= 1000

题解:

该题需求解数组左边之和等于数组右边之和的中间元素的下标,那么就可以先对数组元素进行求和,然后设置一个 leftSum 用于保存左边元素之和,左边每次加 nums[i-1]sum 每次减 nums[i] ,由此 nums[i] 正好就为中间元素,i 即为所求。

【注意】:当中心索引左边或右边没有元素时,即为0;

Java代码求解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public static int pivotIndex(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i]; //对数组求和
}
int leftSum = 0; //左边之和
for (int i = 0; i < nums.length; i++) {
if (i - 1 >= 0) {
leftSum += nums[i - 1];
}
sum -= nums[i];
if (leftSum == sum) {
return i;
}

}
return -1;
}
}

改进版

设数组元素之和为 total , 左侧元素之和为 sum ,则右侧之和为 total - nums[i] - sum 。左右两侧相等即为 sum = total -nums[i] - sum ,即 2 * sum + nums[i] = total 。

Java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int pivotIndex(int[] nums) {
int total = Arrays.stream(nums).sum();
int sum = 0;
for (int i = 0; i < nums.length; ++i) {
if (2 * sum + nums[i] == total) {
return i;
}
sum += nums[i];
}
return -1;
}
}

LeetCode35(搜索插入位置)

题目描述:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

1
2
输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

1
2
输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

1
2
输入: nums = [1,3,5,6], target = 7
输出: 4

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums无重复元素升序 排列数组
  • -104 <= target <= 104

题解:

首先,先判断数组中有没有目标元素,可用 Arrays.binarySearch() 如果数组中有目标元素,则直接返回 index ,如果没有将返回 *(-(insertion point)-1)*,即这个目标元素应该在该升序排序数组中的位置取负再减1,所以如果元素中没有目标元素,那么直接返回 -index-1

Java代码求解如下:

1
2
3
4
5
6
7
8
9
10
import java.util.Arrays;
class Solution {
public int searchInsert(int[] nums, int target) {
int index = Arrays.binarySearch(nums,target);
if (index < 0) {
return -index-1;
}
return index;
}
}

LeetCode48(旋转图像)

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在** 原地** 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

img

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

示例 2:

img

1
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]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

题解:

观察可知,旋转后的新矩阵的第一行即为从最后一行开始向上依次取第一个元素组成,第二行为从最后一行开始向上依次取第二个元算组成,以此类推。
那么就可以使用辅助数组,存储从旋转前数组中取出的元素组成的新数组,最后再把辅助数组赋值给原数组即可。

遍历数组时,辅助数组需要从第一个位置到最后一个位置逐个遍历,而原数组需要从一维 matrix.length-1—>0,二维从 0—>matrix.length-1

Java代码求解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public void rotate(int[][] matrix) {
int[][] newM = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = matrix.length - 1; j >= 0; j--) {
newM[i][matrix.length - j - 1] = matrix[j][i];
}
}
for (int i = 0; i < matrix.length; i++) {
matrix[i] = Arrays.copyOf(newM[i], newM[i].length);
}
}
}

面试题 01.08.零矩阵

题目描述:

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例 1:

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

示例 2:

1
2
3
4
5
6
7
8
9
10
11
12
输入:
[
[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的位置,可以设置一个标记0的数组,里面存储0的位置,初始化数组全为零,如果遍历到哪个元素为0,则将标记数组中相同位置设为 -1 ,标记完成后,再开始遍历标记数组,遇到-1的地方,将其原矩阵行和列清零。

Java求解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public static void setZeroes(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
int[][] label = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0){
label[i][j] = -1;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (label[i][j] == -1){
for (int k = 0; k < n; k++) {
matrix[k][j] = 0;
}
for (int k = 0; k < m; k++) {
matrix[i][k] = 0;
}
}
}
}
}
}

改进

可以单独标记行和列,这样在对数组中元素0所在的行和列进行清零时,只要判断该元素在不在元素0所在的行或列即可。

Java求解代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public static void setZeroes(int[][] matrix) {

int n = matrix.length;
int m = matrix[0].length;
int [] row = new int[n];
int [] col = new int[m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0){
row[i] = -1;
col[j] = -1;
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (row[i] == -1 || col[j] == -1){
matrix[i][j] = 0;
}
}
}
}
}