【剑指offer|图解|双指针】训练计划 I + 删除有序数组中的重复项

在这里插入图片描述
🌈个人主页:聆风吟
🔥系列专栏:数据结构算法模板
🔖少年有梦不应止于心动,更要付诸行动。


📋前言

    💬 hello! 小伙伴们大家好哇,我们通过图文已经对顺序表进行了详细解析,相信小伙伴们已经对顺序表有的初步了解,今天我们在结合三道面试题对顺序表进一步巩固,如果有需要复习的小伙伴可以点击此处链接《图解顺序表》跳转过去对顺序表进行回顾。
    📚 系列专栏:本期文章收录在《剑指offer每日一练》,大家有兴趣可以浏览和关注,后面将会有更多精彩内容!
    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝



一. ⛳️训练计划 I

⌈ 在线OJ链接,可以转至此处自行练习 ⌋

题目:
教练使用整数数组 actions 记录一系列核心肌群训练项目编号。为增强训练趣味性,需要将所有奇数编号训练项目调整至偶数编号训练项目之前。请将调整后的训练项目编号以 数组 形式返回。

示例:

输入: actions = [ 1, 2, 3, 4, 5 ]
输出: [ 1, 3, 5, 2, 4 ]
解释: 正确答案不为一

限制:

  • 0 <= actions.length <= 50000
  • 0 <= actions[i] <= 10000

解题思路:
采用双指针
定义双指针 leftright 分别位于数组的两端,循环执行:

  1. 指针 left 从左向右寻找偶数;
  2. 指针 right 从右向左寻找奇数;
  3. 将指针 left 找到的偶数与指针 right 找到的奇数进行交换。

在这里插入图片描述

c++代码:

class Solution {
public:
    vector<int> trainingPlan(vector<int>& actions) {
        int sz = actions.size();

        int l = 0;//左指针
        int r = sz -1;//右指针
        while(l < r){
            while(l < r && actions[l] % 2 != 0) l++;//从左向右找首个偶数
            while(l < r && actions[r] % 2 == 0) r--;//从右向左找首个奇数
            swap(actions[l], actions[r]);//交换
        }

        return actions;
    }
};


二. ⛳️查找总价格为目标值的两个商品

⌈ 在线OJ链接,可以转至此处自行练习 ⌋

题目:
购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况,返回任一结果即可。

示例:

输入: price = [ 3, 4, 12, 15 ], target = 16
输出: [ 4, 12 ] 或者 [ 12, 4 ]

限制:

  • 1 <= price.length <= 10^5
  • 1 <= price[i] <= 10^6
  • 1 <= target <= 2*10^6

解题思路:
采用双指针
定义双指针 leftright 分别位于数组的左右两端,循环执行(当指针相遇时,跳出):

  1. 计算sum = price[left] + price[right];
  2. 如果sum > target,则指针 right 向左移动,即执行 right--;
  3. 如果sum < target,则指针 left 向右移动,即执行 left++;
  4. 如果sum = target,则立即返回数组{ price[left],price[right] }

若循环结束,则返回空数组,代表无和为 target 的数字组合。
在这里插入图片描述

c++代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int sz = price.size();

        int l = 0;//左指针
        int r = sz - 1;//右指针
        int sum = 0;
        while(l < r){
            sum = price[l] + price[r];
            if(sum > target) r--;
            else if(sum < target) l++;
            else return {price[l], price[r]};
        }

        return {};
    }
};


三. ⛳️删除有序数组中的重复项

⌈ 在线OJ链接,可以转至此处自行练习 ⌋

题目:
给你一个 非严格递增排列 的数组nums,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑nums的唯一元素的数量为k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组nums ,使nums的前k个元素包含唯一元素,并按照它们最初在nums中出现的顺序排列。nums的其余元素与nums的大小不重要。
  • 返回k

示例:

输入: nums = [ 1, 1, 2 ]
输出: 2, nums = [ 1, 2, _ ]
解释: 函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

限制:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums 已按 非严格递增 排列

解题思路:
采用双指针
定义双指针 leftright 分别位于数组的下表为 0 和为 1 的位置,循环执行(当right走到数组末尾时停止):

  1. 如果nums[left] != nums[right],执行nums[++left] = nums[right++];
  2. 如果nums[left] == nums[right],执行right自增加1。

若循环结束,则返回right+1即可。
在这里插入图片描述

c语言代码:

int removeDuplicates(int* nums, int numsSize){
    //定义left指向数组下标为0的位置
    int left = 0;
    //定义right指向数组下标为1的位置
    int right = 1;

    //循环:当right指向数组末尾时停止
    while(right < numsSize)
    {
        if(nums[left] != nums[right])
        {
            //优化前
            // left++;
            // nums[left] = nums[right];
            // right++;

            //优化后
            nums[++left] = nums[right++];
        }
        else
        {
            right++;
        }
    }

    //返回结果
    return left+1;
}


📝结尾

     今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!
在这里插入图片描述

  • 44
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 52
    评论
评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聆风吟_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值