【LeetCode题解】数组Array
1. 数组
直观地看,数组(Array)为一个二元组<index, value>的集合——对于每一个index,都有一个value与之对应。C语言中,以“连续的存储单元”实现数组:
int arr[5], *p_arr[5];
数组提供以\(O(1)\)的复杂度访问元素,下标从0开始。但是,数组的插入、删除操作却非常耗时,因为这涉及到了元素间的移动。
常见的矩阵,可用二维数组表示。二维数组本质上是一个一维数组,其中每个行单元也是一个一维数组,比如,二维数组int x[3][5]的存储结构如下:

从上图可以看出,x共有4块存储区,一块用于用以存放行单元指针(x[0:2]),另外三块用于存放每一个行单元对应的一维数组。因此,x是一个长度为3的一维数组,而行单元x[0]又是一个长度为5的一维数组。
2. 题解
| LeetCode题目 | 归类 |
|---|---|
| 26. Remove Duplicates from Sorted Array | 删除 |
| 80. Remove Duplicates from Sorted Array II | 删除 |
| 27. Remove Element | 删除 |
| 88. Merge Sorted Array | 合并 |
| 268. Missing Number | 查找 |
| 41. First Missing Positive | 查找 |
| 287. Find the Duplicate Number | 查找 |
| 189. Rotate Array | 旋转 |
| 54. Spiral Matrix | 矩阵遍历 |
| 59. Spiral Matrix II | |
| 48. Rotate Image | 矩阵旋转 |
| 73. Set Matrix Zeroes |
26. Remove Duplicates from Sorted Array
移除数组中重复的元素,由于数据是有序的,所以重复元素一定是相邻的。用两个pointers,一个用于新数组生成,一个用于遍历原数组:
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 1;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i - 1])
nums[i++] = nums[j];
}
return i;
}
80. Remove Duplicates from Sorted Array II
上一问题的变种,新数组中最多允许两个重复元素。
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 2;
for (int j = 2; j < nums.length; j++) {
if (nums[j] != nums[i - 2])
nums[i++] = nums[j];
}
return i;
}
27. Remove Element
移去数组中出现的指定元素。也是用两个pointers遍历数组,从头尾两端往中间移动交换:
public int removeElement(int[] nums, int val) {
int i = 0, j = nums.length - 1;
while (i <= j) {
while (j >= i && nums[j] == val) j--; // reduce array size
if (i <= j && nums[i] == val) {
nums[i] = nums[j]; // swap between the current and the last
j--; // reduce array size
}
i++;
}
return j + 1;
}
88. Merge Sorted Array
合并两个有序数组,从后往前开始合并:
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1, j = n - 1, k = m + n - 1;
while (j >= 0) {
if (i >= 0 && nums1[i] > nums2[j])
nums1[k--] = nums1[i--];
else
nums1[k--] = nums2[j--];
}
}
268. Missing Number
数的范围[0,n],找出缺失的数。思路:目标和n*(n+1)/2减去数组之和即为缺失数。
public int missingNumber(int[] nums) {
int sum = 0, n = nums.length;
for (int i : nums) {
sum += i;
}
return n * (n + 1) / 2 - sum;
}
41. First Missing Positive
找出缺失的第一个正数,数组的正数范围在[1,n]。将正数i放在i-1位置上,然后找出缺失数。
public int firstMissingPositive(int[] nums) {
for (int i = 0; i < nums.length; i++) {
while (nums[i] > 0 && nums[i] <= nums.length && nums[i] != nums[nums[i] - 1])
swap(nums, i, nums[i] - 1);
}
for (int i = 0; i < nums.length; i++) {
if (nums[i] != i + 1)
return i + 1;
}
return nums.length + 1;
}
private void swap(int[] A, int a, int b) {
int temp = A[a];
A[a] = A[b];
A[b] = temp;
}
287. Find the Duplicate Number
从数组中找出重复数,且数组中的数的范围在[1,n],且只有一个数重复,重复次数>=2。解决思路:将数组看作一个移动链表,按照index=a[index]方式进行移动;那么重复元素会使之成为一个有环的链表,并且重复的元素为环的开始。故可用快慢两个指针来解决。
public int findDuplicate(int[] nums) {
int slow = nums[0], fast = nums[nums[0]];
while (slow != fast) { // find the entry point where slow and fast meet
slow = nums[slow];
fast = nums[nums[fast]];
}
for (fast = 0; slow != fast; ) { // find the entry point where the cycle begins
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
189. Rotate Array
指定一个数组截断点,将左子数组拼接到右子数组后。解决思路:现将整个数组逆序,再将逆序后的左部分逆序、右部分逆序。
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
// reverse array from begin to end
private void reverse(int[] a, int begin, int end) {
for (int temp; begin < end; begin++, end--) {
temp = a[begin];
a[begin] = a[end];
a[end] = temp;
}
}
54. Spiral Matrix
二维数组螺旋形遍历。
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new LinkedList<>();
if (matrix.length == 0) return result;
int m = matrix.length, n = matrix[0].length;
for (int start = 0; m - 1 >= 2 * start && n - 1 >= 2 * start; start++) {
int rowEnd = m - start - 1, colEnd = n - start - 1, i, j;
for (j = start; j <= colEnd; j++) // left move
result.add(matrix[start][j]);
if (rowEnd == start) break;
for (i = start + 1; i <= rowEnd; i++) // down move
result.add(matrix[i][colEnd]);
if (colEnd == start) break;
for (j = colEnd - 1; j >= start; j--) // right move
result.add(matrix[rowEnd][j]);
for (i = rowEnd - 1; i > start; i--) // top move
result.add(matrix[i][start]);
}
return result;
}
59. Spiral Matrix II
上一问题的变种,生成螺旋形二维数组。
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
for (int start = 0, cnt = 1; n - 1 >= 2 * start; start++) {
int end = n - start - 1, i, j;
for (j = start; j <= end; j++, cnt++) // left move
matrix[start][j] = cnt;
if (end == start) break;
for (i = start + 1; i <= end; i++, cnt++) // down move
matrix[i][end] = cnt;
for (j = end - 1; j >= start; j--, cnt++) // right move
matrix[end][j] = cnt;
for (i = end - 1; i > start; i--, cnt++) // top move
matrix[i][start] = cnt;
}
return matrix;
}
48. Rotate Image
顺时针旋转矩阵,相当于每一次把四个对应元素做旋转。
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n / 2; i++) {
for (int j = i; j < n - i - 1; 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;
}
}
}
73. Set Matrix Zeroes
将有0元素的行与列全置为0;用两个set保存这样的行列,然后再置为0——空间复杂度大概为\(O(m+n)\),并非为最优解。
public void setZeroes(int[][] matrix) {
if (matrix.length == 0) return;
int m = matrix.length, n = matrix[0].length;
Set<Integer> rows = new HashSet<>(); // mark rows which contain 0
Set<Integer> columns = new HashSet<>(); // mark columns which contain 0
// phase 1: find zeroes
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
rows.add(i);
columns.add(j);
}
}
}
// phase 2: set rows and columns
for (Integer i : rows) {
for (int j = 0; j < n; j++) {
matrix[i][j] = 0;
}
}
for (Integer j : columns) {
for (int i = 0; i < m; i++) {
matrix[i][j] = 0;
}
}
}
【LeetCode题解】数组Array的更多相关文章
- leetCode题解之Array Partition I
1.题目描述 2.分析 按照题目要求,主要就是对数组进行排序 3.代码 int arrayPairSum(vector<int>& nums) { ; sort( nums.beg ...
- [LeetCode 题解] Search in Rotated Sorted Array
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 题目描述 Suppose an array ...
- 【LeetCode题解】350_两个数组的交集Ⅱ
目录 [LeetCode题解]350_两个数组的交集Ⅱ 描述 方法一:映射 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 Python 实现 [Lee ...
- 【LeetCode题解】349_两个数组的交集
目录 [LeetCode题解]349_两个数组的交集 描述 方法一:两个哈希表 Java 实现 类似的 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 ...
- [LeetCode 题解]:Best Time to Buy and Sell Stock
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Say you ha ...
- [LeetCode题解]: Sort Colors
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given an a ...
- [LeetCode 题解]: plusOne
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a no ...
- 算法与数据结构基础 - 数组(Array)
数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...
- LeetCode:Convert Sorted Array to Binary Search Tree,Convert Sorted List to Binary Search Tree
LeetCode:Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in asce ...
- leetcode题解-122买卖股票的最佳时期
题目 leetcode题解-122.买卖股票的最佳时机:https://www.yanbinghu.com/2019/03/14/30893.html 题目详情 给定一个数组,它的第 i 个元素是一支 ...
随机推荐
- 编译安装CoreSeek-4.1
编译安装CoreSeek-4.1 yum -y install expat-devel* wget http://www.coreseek.cn/uploads/csft/4.0/coreseek- ...
- strlen sizeof strcat strcpy区别
strlen(p): 能计算出p指向字符串的长度(以当前p的位置开始),不包含终止字符'\0': p可以声明为char* p或者char p[],这两种形式strlen均能正确计算. sizeof ...
- JS实现静态html页面左侧导航,右侧连接页面
本人前端小菜,想实现左侧导航固定,右侧链接页面,不想用iframe,请问各位有什么好的建议,最好有个demo,谢谢
- FMDB事务的使用
http://blog.csdn.net/qq_29892943/article/details/50541439 首先,说一下事务是什么,比如说我们有一个学生表和一个学生成绩表,而且一个学生对应一个 ...
- tp框架 使用ajax
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8&quo ...
- Android如何调用第三方SO库(转)
源:Android如何调用第三方SO库 问题描述:Android如何调用第三方SO库:已知条件:SO库为Android版本连接库(*.so文件),并提供了详细的接口说明:已了解解决方案:1.将SO文件 ...
- Delphi调用Android的.so文件(转)
原地址:http://zhidao.baidu.com/link?url=fzqefMM44ljXA5BnAbkX44SapCUteyzlXFvGLKvukBivm9AB-w39P_h7eX1ty-G ...
- linux下实现ftp匿名用户的上传和下载文件功能
1.配置/etc//vsftpd/vsftpd.conf 文件如下: 打开文件,改变如下选项,如果文件中没有该选项,需要自己手动编写该选项 write_enable=YES anonymous_ena ...
- Java琐碎
final final只能用来保证原始数据类型的实例变量的不可变性,而无法用于引用类型的变量.如果一个引用类型的实例变量含有修饰符final,该实例变量的值(某个对象的引用)就永远无法改变了--它将永 ...
- Maven项目中pom文件分析
pom英文全称: project object model 1.概述 pom.xml文件描述了maven项目的基本信息,比如groupId,artifactId,version等.也可以对maven项 ...