双指针

1.1 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1)额外空间的条件下完成。
在这里插入图片描述
(双指针移动) O(n)

  • 如果 nums 的长度是 0,直接返回 0。
  • 初始令 k 为 0,i 从位置 1 开始遍历,若发现 nums[i] 和 nums[k]不相等,则说明找到新的元素,并且 nums[++k] 赋值为 nums[i]。
  • i 向后移动直到末尾。
class Solution {
   
public:
    int removeDuplicates(vector<int>& nums) {
   
        if (nums.size() == 0)
            return 0;

        int k = 0;
        for (int i = 1; i < nums.size(); i++)
            if (nums[i] != nums[k])
                nums[++k] = nums[i];

        return k + 1;
    }
};

1.1 给定一个有序数组,请删除里面的重复元素,使得每个数最多出现 2次,并返回新数组的长度。
需要使用 原地算法,即最多只能使用额外 O(1)空间。

在这里插入图片描述
O(n)
由于数组有序,所以相同元素一定是相邻的。
我们定义一个指针 k,表示新数组的末尾,然后从前往后扫描原数组,如果当前数不等于 nums[k]且不等于 nums[k−1],则将当前数插入新数组的末尾。

class Solution {
   
public:
    int removeDuplicates(vector<int>& nums) {
   
        if (nums.size() < 3) return nums.size();
        int k = 1;
        for (int i = 2; i < nums.size(); i ++ )
            if (nums[i] != nums[k - 1])//nums[i]==nums[k-1]就一定会有nums[i]==nums[k]
                nums[ ++ k] = nums[i];
        k ++ ;
        return k;
    }
};

时间复杂度分析:总共对原数组仅扫描了一遍,所以总时间复杂度是 O(n)。
1.2 调整数组顺序使奇数位于偶数前面
(双指针扫描) O(n)
用两个指针分别从首尾开始,往中间扫描。扫描时保证第一个指针前面的数都是奇数,第二个指针后面的数都是偶数。

每次迭代时需要进行的操作:

  • 第一个指针一直往后走,直到遇到第一个偶数为止;
  • 第二个指针一直往前走,直到遇到第一个奇数为止;
  • 交换两个指针指向的位置上的数,再进入下一层迭代,直到两个指针相遇为止;

时间复杂度
当两个指针相遇时,走过的总路程长度是 nn,所以时间复杂度是 O(n)。

class Solution {
   
public:
    void reOrderArray(vector<int> &array) {
   
         int l = 0, r = array.size() - 1;
         while (l < r) {
   
             while (l < r && array[l] % 2 == 1) l ++ ;
             while (l < r && array[r] % 2 == 0) r -- ;
             if (l < r) swap(array[l], array[r]);
         }
    }
};

1.2 编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
在这里插入图片描述

class Solution {
   
public:
    string reverseVowels(string s) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值