【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 个元素是一支 ...
随机推荐
- phpstrom 2016.2 注册服务器地址
无意中发现的,亲测可用:http://114.215.133.70:41017
- 缩进(Python很将就格式)
空白在Python中是重要的.事实上行首的空白是重要的.它称为缩进.在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组.这意味着同一层次的语句必须有相同的缩进.每一组这样 ...
- window.location获取URL中各部分
博客分类: JAVASCRIPT JavaScriptASP.netSchemeASP网络协议 URL即:统一资源定位符 (Uniform Resource Locator, URL) 完整的URL ...
- python模块 ---logging模块
摘要by crazyhacking: 与log4cxx一样,分为三个部分,logger, handler,formatter. 详细内容参考:1官网http://docs.python.org/2/h ...
- Ext分页之php中,真分页显示
这是我经过很多天调试的真分页显示Ext组件 显示页面ext.php <html> <head> <meta http-equiv="Content-Type&q ...
- OO设计原则 -- OO设计的原则及设计过程的全面总结
这部分增加一点自己的感想,OO设计原则下面讲述的很清晰;看完之后有点感想如果我们在实际开发当中能够把这些原则熟烂于心的话那我们的代码质量和个人能力会有很显著的提神.根据自己的实际经验看很多开发者在开发 ...
- 【转】程序员必须知道的几个Git代码托管平台
一.VS2013中克隆远程Git仓库和SSH的配置 1.VS2013中克隆远程项目 首先感谢园友的评论和补充,今日又仔细看了一下,VS2013中是可以克隆项目的,只是我一直用的GitHub来克隆的 ...
- RabbitMQ消息队列(二):”Hello, World“
本文将使用Python(pika 0.9.8)实现从Producer到Consumer传递数据”Hello, World“. 首先复习一下上篇所学:RabbitMQ实现了AMQP定义的消息队列.它实现 ...
- react programming
So you're curious in learning this new thing called Reactive Programming, particularly its variant c ...
- linux与windows回车换行符的区别
转自:http://www.cnblogs.com/dartagnan/archive/2010/12/14/2003499.html “回车”(carriage return)VS “换行”(li ...