作者:一个喜欢猫咪的的程序员
专栏:《Leetcode》
喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》
目录
26.删除有序数组中的重复项:
26. 删除有序数组中的重复项
https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
题目:
示例:
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
思路:
思路一:(双指针暴力解法)
利用双指针begin和end一前一后,每次begin和end相等时,设一个变量i=begin,利用i来将右边的值赋给左边,以此循环左边都是一次出现的值了。
初始条件:begin=0 end=1
结束条件:begin>=size||endsize||end==size-1的情况
迭代原理:
当nums[begin]=nums[begin+1]的时候,nums[i]=nums[i+1]向左覆盖,size--,另外的情况,nize--就可以了
时间复杂度:O(N^2) 空间复杂度:O(1)
思路二:双指针优化
还是利用两个指针,因为我们返回值个数,只检查前numsSize个值是否符合条件,但后面的值不管,所以我们可以这样。
当begin所值的值与end所指的值想同时,我们end后移一位,然后如果这两个值所指的值相等,继续此操作,如果不相等,先进行begin后移一位,然后将把end所指的值赋给begin所指的位置,然后end后移(如果不先begin++再赋值的话,会顺序不对)。
思路一:
int removeDuplicates(int* nums, int numsSize) { int begin = 0; int end = 1; while (begin < numsSize && end < numsSize) { while (nums[begin] == nums[begin+1]) { if(end==numsSize-1) { numsSize--; break; } else { for (int i = end; i < numsSize-1; i++) { nums[i] = nums[i + 1]; } numsSize--; } } begin = end; end++; } return numsSize; }
思路二:
int removeDuplicates(int* nums, int numsSize) { int begin=0; int end=1; while(end<numsSize) { if(nums[begin]==nums[end]) ; else { begin++; nums[begin]=nums[end]; } end++; } return begin+1; }
88.合并两个有序数组:
88. 合并两个有序数组
https://leetcode.cn/problems/merge-sorted-array/
题目:
示例:
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。
示例 3:
输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [] 和 [1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。
思路:
思路一: 利用额外数组法
将两个数组元素进行比较,较小的赋值给额外数组sort。
时间复杂度:O(m+n) 空间复杂度:O(m+n)
思路二: 逆向双指针
我们在思路一的基础上优化,我们双指针一般是一前一后或者两个在头作比较,本题我们双指针两个都在后面,作比较哪个比较大再放在nums1的尾部,然后分别自减。这样就可以避免从前面作比较后造成的原nums1前面的元素丢失了。
时间复杂度:O(m+n) 空间复杂度:O(1)
思路一:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) { int q1 = 0; int q2 = 0; int sort[m + n]; if (n == 0) ; else { for (int i = 0; i < m + n; i++) { if (q2 == n) sort[i] = nums1[q1++]; else if (q1 == m) sort[i] = nums2[q2++]; else if (nums1[q1] > nums2[q2]) sort[i] = nums2[q2++]; else sort[i] = nums1[q1++]; } for (int i = 0; i < m + n; i++) { nums1[i] = sort[i]; } } }
思路二:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){ int end1=m-1; int end2=n-1; int i=n+m-1; while(end1>=0||end2>=0) { if(end2<0) nums1[i--]=nums1[end1--]; else if(end1<0) nums1[i--]=nums2[end2--]; else if(nums1[end1]>nums2[end2]) nums1[i--]=nums1[end1--]; else nums1[i--]=nums2[end2--]; } }