2216. 美化数组的最少删除数

给你一个下标从 0 开始的整数数组 nums ,如果满足下述条件,则认为数组 nums 是一个 美丽数组 :

  • nums.length 为偶数
  • 对所有满足 i % 2 == 0 的下标 i ,nums[i] != nums[i + 1] 均成立

注意,空数组同样认为是美丽数组。

你可以从 nums 中删除任意数量的元素。当你删除一个元素时,被删除元素右侧的所有元素将会向左移动一个单位以填补空缺,而左侧的元素将会保持 不变 。

返回使 nums 变为美丽数组所需删除的 最少 元素数目

贪心:删除一个数只会影响后面的数,不会影响前面的数,所以该问题满足最优子结构。

[1,1,..]第一个1必须要删,如果不删,则该数组不是 美丽数组。所以当前最优解是全局最优解,时使用贪心。

所以当遍历到下标i时,如果i是偶数,并且nums[i]==nums[i+1]那么一定要删除,第i个数一定要删除。

如果i是奇数或不相等,跳过。

需要使用一个变量维护前面删除数的个数,这样可以计算i对应删除后的下标,然后计算。

最后一个数需要单独考虑。如果是最后数组是奇数个数,就需要把最后一个数删掉。

经验:举个例子,看什么时候需要操作。

class Solution {
public:
    int minDeletion(vector<int>& nums) {
        int cnt = 0;
        int n = nums.size();
        for(int i=0;i<nums.size();i++){
            //[1,1]第一个1必须要删,否则后面就没有机会删,所以是当前最优解就是删除第一个1
            //如果删完之后的下标idx%2==0并且nums[i]==nums[i+1],那,么nums[i]就需要被删除。
             if(i+1<n&&(i-cnt)%2==0&&nums[i]==nums[i+1])cnt++;
        }
        if((n-cnt)%2!=0){
            cnt++;
        }
        return cnt;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.