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的更多相关文章

  1. leetCode题解之Array Partition I

    1.题目描述 2.分析 按照题目要求,主要就是对数组进行排序 3.代码 int arrayPairSum(vector<int>& nums) { ; sort( nums.beg ...

  2. [LeetCode 题解] Search in Rotated Sorted Array

    前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 题目描述 Suppose an array ...

  3. 【LeetCode题解】350_两个数组的交集Ⅱ

    目录 [LeetCode题解]350_两个数组的交集Ⅱ 描述 方法一:映射 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 Python 实现 [Lee ...

  4. 【LeetCode题解】349_两个数组的交集

    目录 [LeetCode题解]349_两个数组的交集 描述 方法一:两个哈希表 Java 实现 类似的 Java 实现 Python 实现 类似的 Python 实现 方法二:双指针 Java 实现 ...

  5. [LeetCode 题解]:Best Time to Buy and Sell Stock

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Say you ha ...

  6. [LeetCode题解]: Sort Colors

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Given an a ...

  7. [LeetCode 题解]: plusOne

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Given a no ...

  8. 算法与数据结构基础 - 数组(Array)

    数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...

  9. 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 ...

  10. leetcode题解-122买卖股票的最佳时期

    题目 leetcode题解-122.买卖股票的最佳时机:https://www.yanbinghu.com/2019/03/14/30893.html 题目详情 给定一个数组,它的第 i 个元素是一支 ...

随机推荐

  1. Ubuntu和win10双系统Grup无法引导解决方案

    通常我们经常安装双系统, 但是有时候安装完系统无法正常引导, 以下就说明Ubuntu和win10双系统, win10在grub界面不断循环的解决方案 直接在win10启动项目上按e进入编辑模式 在文档 ...

  2. ELK 日志分析体系

    ELK   日志分析体系 ELK 是指 Elasticsearch.Logstash.Kibana三个开源软件的组合. logstash                       负责日志的收集,处 ...

  3. ngx_http_core_module模块提供的变量

    ngx_http_core_module模块在处理请求时,会有大量的变量,这些变量可以通过访问日志来记录下来,也可以用于其它nginx模块.在我们对请求做策略如改写等等都会使用到一些变量,顺便对ngx ...

  4. (简单) FZU 2150 Fire Game ,Floyd。

    Problem Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board ...

  5. linux devel包 和 非devel包的区别

    devel 包主要是供开发用,至少包括以下2个东西: 1. 头文件 2. 链接库 有的还含有开发文档或演示代码. 以 glib 和 glib-devel 为例: 如果你安装基于 glib 开发的程序, ...

  6. LPC1788的spi使用

    #ifndef __SPI_H_ #define __SPI_H_ #include "common.h" #include "delay.h" // cs p ...

  7. LPC1768的USB使用-枚举过程

    枚举过程如下 #ifndef __USBCORE_H__ #define __USBCORE_H__ /* USB端点0 发送数据结构体*/ typedef struct _USB_EP_DATA { ...

  8. Android源码编译jar包BUILD_JAVA_LIBRARY 与BUILD_STATIC_JAVA_LIBRARY的区别(三)

    继续, 上文提到的是用BUILD_STATIC_JAVA_LIBRARY在Android4.2源码下编译出来的jar包可以在Eclipse(SDK版本4.1)上使用, 找来Android6.0的源码, ...

  9. 异常捕获拒绝闪退 让应用从容的崩溃UncaughtExceptionHandler

    虽然大家都不愿意看到程序崩溃,但可能崩溃是每个应用必须面对的现实,既然崩溃已经发生,无法阻挡了,那我们就让它崩也崩得淡定点吧. IOS SDK中提供了一个现成的函数 NSSetUncaughtExce ...

  10. mysql 省市联动sql 语句

    /*MySQL Data TransferSource Host: localhostSource Database: virgoTarget Host: localhostTarget Databa ...