【Leetcode】移除元素、轮转数组

简介: 【Leetcode】移除元素、轮转数组

作者:一个喜欢猫咪的的程序员

专栏:《Leetcode》

喜欢的话:世间因为少年的挺身而出,而更加瑰丽。                                  ——《人民日报》

目录

27. 移除元素

189.轮转数组:


27. 移除元素


27. 移除元素

https://leetcode.cn/problems/remove-element/


题目:


给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例:


示例 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],也会被视作正确答案。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2

输出:5, nums = [0,1,4,0,3]

解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。


思路一:


我们以示例2为例子:


0,1,2,2,3,0,4,2       我们不是要返回整数嘛,我们可以先算出来等于val的个数,利用numsSize--来算出返回的整数。我们从0(i)开始往后遍历,找到等于val的值,如果有就从numsSize-1的位置(f)向前遍历找一个不等val的值将其赋给val这个值的下标(比如:将示例2中的4赋给第一个2。)然后f-1一下找到上一个位置(这里不是j-1是因为要保证后面n个数都要被找过,直接用j-1的话会少一个或者两个...)。当我们把f遍历到i的下一个位置时,从后面遍历上来这个循环就不会循环了,我们需要额外写这种情况。


时间复杂度:O(N^2)  空间复杂度:O(1)


思路二:双指针


利用左指针left找到等于val的值,如果将右指针right位置的值赋过去,然后右指针左移一位right--


如果赋值过来的值也是val,将右指针的下一个值也赋值过来就好了,直到左指针的值不为val。


当左指针left 和右指针 right重合的时候,左右指针遍历完数组中所有的元素。


时间复杂度:O(N)   空间复杂度:O(1)


代码实现:

思路一:

int removeElement(int* nums, int numsSize, int val){
    int n=numsSize;
    for(int i=0;i<numsSize;i++)
    {
        if(*(nums+i)==val)
        n--;
    }
    int f=numsSize-1;
    for(int i=0;i<numsSize;i++)
    {
        if(*(nums+i)==val)
        {
            if(i+1==f)
            {
                *(nums+i)=*(nums+i+1);
                continue;
            }
            else
            {
              for(int j=f;j>i;j--)
               {
                if(*(nums+j)!=val)
                {
                    *(nums+i)=*(nums+j);
                    f=j-1;
                    break;
                }
               }
            }
        }
    }
    numsSize=n;
    return numsSize;
}

思路二:

int removeElement(int* nums, int numsSize, int val){
    int left=0;
    int right=numsSize;
    while(left<right)
    {
        if(*(nums+left)==val)
        {
            *(nums+left)=*(nums+right-1);
            right--;
        }
        else
        left++;
    }
    return left;
}


189.轮转数组:


image.png

题目:

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例:

示例 1:


输入: 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]

示例 2:


输入:nums = [-1,-100,3,99], k = 2

输出:[3,99,-1,-100]

解释:

向右轮转 1 步: [99,-1,-100,3]

向右轮转 2 步: [3,99,-1,-100]


思路:


思路一:利用额外的数组


将后k个元素先存在额外数组n[numsSize]中,剩下的numssize-k个元素在存进去这个额外数组中,然后再将这个额外数组赋给nums。


时间复杂度:O(N)   空间复杂度:O(N)

思路二:数组翻转


将前numsSize-k个先倒序,再将后k个倒序,然后再整体倒序。


时间复杂度:O(N)   空间复杂度:O(1)


代码实现:


思路一:

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

思路二:

void reverse(int* n,int begin,int end)
{
    while(begin<end)
    {
        int tmp=*(n+begin);
        *(n+begin)=*(n+end);
        *(n+end)=tmp;
        end--;
        begin++;
    }
}
void rotate(int* nums, int numsSize, int k){
    k=k%numsSize;
    reverse(nums,0,numsSize-k-1);
    reverse(nums,numsSize-k,numsSize-1);
    reverse(nums,0,numsSize-1);
}
相关文章
|
15天前
|
存储 C语言
Leetcode—— 删除排序数组中的重复项——C语言
Leetcode—— 删除排序数组中的重复项——C语言
|
15天前
|
算法 C语言
Leetcode----旋转数组 ------C语言篇
Leetcode----旋转数组 ------C语言篇
|
9天前
题目----力扣--移除链表元素
题目----力扣--移除链表元素
15 1
|
11天前
|
存储 算法 索引
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
23 1
|
11天前
|
索引
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
【力扣刷题】数组实现栈、后缀表达式(逆波兰表达式)求值、中缀表达式转换为后缀表达式(无括号&&有括号)
16 0
|
13天前
DAY-4 | 力扣 - 求自身以外数组的乘积:区间划分,左右累乘,巧求乘积
该文档是关于LeetCode上的一道题目“Product of Array Except Self”的题解。提供了两种解题方法,一是暴力破解,即计算所有数的乘积后再逐个除以当前元素;二是左右累乘法,通过两次遍历数组分别计算左侧和右侧元素的乘积,避免了除法操作。其中,左右累乘法更优,代码实现中展示了这种方法。
20 1
|
15天前
|
存储 算法
【数据结构与算法 | 基础篇】[数组专题]力扣88
【数据结构与算法 | 基础篇】[数组专题]力扣88
|
15天前
|
算法 C语言
Leetcode_203.移除链表元素—C语言
Leetcode_203.移除链表元素—C语言
|
16天前
力扣2834. 找出美丽数组的最小和
力扣2834. 找出美丽数组的最小和
|
16天前
力扣421. 数组中两个数的最大异或值(字典树)
力扣421. 数组中两个数的最大异或值(字典树)