博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【LeetCode题解】数组Array
阅读量:5922 次
发布时间:2019-06-19

本文共 6185 字,大约阅读时间需要 20 分钟。

1. 数组

直观地看,数组(Array)为一个二元组<index, value>的集合——对于每一个index,都有一个value与之对应。C语言中,以“连续的存储单元”实现数组:

int arr[5], *p_arr[5];

数组提供以\(O(1)\)的复杂度访问元素,下标从0开始。但是,数组的插入、删除操作却非常耗时,因为这涉及到了元素间的移动。

常见的矩阵,可用二维数组表示。二维数组本质上是一个一维数组,其中每个行单元也是一个一维数组,比如,二维数组int x[3][5]的存储结构如下:

399159-20170208145119369-1755914170.png

从上图可以看出,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 endprivate 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
spiralOrder(int[][] matrix) { List
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
rows = new HashSet<>(); // mark rows which contain 0 Set
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; } }}

转载于:https://www.cnblogs.com/en-heng/p/6378187.html

你可能感兴趣的文章
MobileIron:移动业务普及 需重新思考安全性
查看>>
程序员那些事:在家办公赚的更多
查看>>
14年优质服务 海科融通进军P2P资金托管
查看>>
CSS十问——好奇心+刨根问底=CSSer
查看>>
希捷与合作伙伴合作解决无人机数据需求
查看>>
不想“打破互联网”?你需要更安全的DNS
查看>>
倪光南:自主创新的华为市值是靠并购的联想10倍
查看>>
《SEO的艺术(原书第2版)》——1.1 搜索引擎的任务
查看>>
欧盟将限制16岁以下孩童用社交网络 需家长同意
查看>>
Redis Web界面管理工具
查看>>
第13代PowerEdge强劲升级 五大独有技术是什么?
查看>>
Facebook新地图增加灾难救援功能!
查看>>
日本电气公司1000万美元建大数据分析中心
查看>>
Ovum点评微信小程序:或对应用商店产生破坏性作用
查看>>
《Arduino开发实战指南:LabVIEW卷》——1.2 Arduino的硬件组成
查看>>
《2040大预言:高科技引擎与社会新秩序》——2.11 坐二手无人车的体力工人
查看>>
阿里研究院启动2017年度淘宝村辅助认证活动(附表格下载)
查看>>
《 FreeSWITCH权威指南》——1.7 VoIP
查看>>
消除障碍 加速推进T-SDN产业发展
查看>>
紧紧跟随NSX认证的步伐
查看>>