顺序表Leetcode习题详解

点击即可跳转:旋转数组

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

方法1:设i为数组的下标,用新数组存储原数组的(i+k) % n的值即可,因为整个为一个环 0-n-1的循环

void rotate(int* nums, int numsSize, int k)
{
    int i;
    int arr[numsSize];
    for (i = 0; i < numsSize; ++i)
    {
        arr[(i + k) % numsSize] = nums[i];
    }
    for (i = 0; i < numsSize; ++i)
    {
        nums[i] = arr[i];
    }
}

方法2:先旋转前n-k个字符,在旋转后面剩余字符,在整体翻转//空间复杂度O(1),没有创建额外的数组,优选

void reverse(int* nums, int left, int right)
{
    while (left < right)
    {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp; 
        left++;
        right--;
    }
}

void rotate(int* nums, int numsSize, int k)
{
    if (k >= numsSize)
    {
        k %= numsSize;
    }
    reverse(nums, 0, numsSize - k - 1);
    reverse(nums, numsSize - k, numsSize - 1);
    reverse(nums, 0, numsSize - 1);
}

双指针问题
合并有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2
中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m
个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 :
输入: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 中的元素。

思路1:从两个数组的最大值开始,依次将最大的元素放置数组的最后一位

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
    int end1 = m - 1, end2 = n - 1, end = m + n - 1;
    while (end1 >= 0 && end2 >= 0)
    {
        if (nums1[end1] < nums2[end2])
        {
            nums1[end] = nums2[end2];
            end2--;
            end--;
        }
        else
        {
            nums1[end] = nums1[end1];
            end1--;
            end--;
        }
    }
    while (end2 >= 0)
    {
        nums1[end] = nums2[end2];
        end2--;
        end--;
    }
    while (end1 >= 0)
    {
        nums1[end--] = nums1[end1--];
    }
}

思路2:将数组2放置数组1里面,然后进行排序

删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序
应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums
的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

思路图解:
在这里插入图片描述

int removeDuplicates(int* nums, int numsSize){
    int i = 0, j = 1, dst = 0;
    if (numsSize == 0)
    {
        return 0;
    }
    while (j < numsSize)//当j和i指向的元素不相同时,把j对应的元素赋值过去
    {
        if (nums[i] == nums[j])
        {
            j++;
        }
        else
        {
            nums[dst] = nums[i];
            dst++;
            i = j;
            j++;
        } 
    }
    //	当退出循环时,j == numssize,此时i还没有赋值过去,因此还要在赋值一次
    nums[dst] = nums[i];
    return dst + 1;
}

移除元素

原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

思路:将数组中不为val的值放到一开始处

int removeElement(int* nums, int numsSize, int val)
{
    int src = 0, dst = 0;
    while (src < numsSize)
    {
        if (nums[src] != val)
        {
            nums[dst] = nums[src];
            dst++;
            src++;
        }
        else
        {
            src++;
        }
    }
    return dst;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值