zoukankan      html  css  js  c++  java
  • 删除排序数组中的重复项

    删除排序数组中的重复项

    描述

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

    不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

    示例 1:

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

    示例 2:

    给定 nums = [0,0,1,1,1,2,2,3,3,4],
    
    函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
    
    你不需要考虑数组中超出新长度后面的元素。
    

    说明:

    为什么返回数值是整数,但输出的答案是数组呢?

    请注意,输入数组是以**“引用”**方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    你可以想象内部操作如下:

    // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
    int len = removeDuplicates(nums);
    
    // 在函数里修改输入数组对于调用者是可见的。
    // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
    for (int i = 0; i < len; i++) {
        print(nums[i]);
    }
    

    思路

    • 从后往前遍历该数组,若当前元素与前一个相同,则从当前元素开始,数组往前移一位
    int removeDuplicates(int* nums, int numsSize){
        int now_size = numsSize;//记录数组大小
        for(int i=numsSize-1;i>0;i--) {
            if(nums[i-1] == nums[i]) {//出现重复元素
                now_size--;//数组大小自减
                for(int j=0;j<numsSize-i-1;j++)//数组前移
                    nums[i+j] = nums[i+j+1];
            }    
        }
        return now_size;
        
    }
    

    进阶

    • 遍历数组,将重复过的元素置为最大或最小值,并记录重复次数,数组大小减重复次数即新数组大小
    • 冒泡排序原数组即可
    void exchange(int* num1,int* num2) {
        int num = *num1;
        *num1 = *num2;
        *num2 = num;
    }
    int removeDuplicates(int* nums, int numsSize){
        int delete_nums = 0;
        for(int i=1;i<numsSize;i++) {
            if(nums[i] == nums[i-1]) {
                delete_nums++;
                nums[i-1] = 0x7fff;
            }
        }
        for(int i=0;i<numsSize;i++) {
            for(int j=numsSize-1;j>i;j--) {
                if(nums[j] < nums[j-1])
                    exchange(nums+j,nums+j-1);
            }
        }
        return numsSize-delete_nums;
    }
    

    进阶二

    • 由于是有序数组,因此最后的数组每一位都是递增且唯一的,所以第一位一定不需要动,从第二位开始,往后遍历数组,大于第一位则可与第二位交换,然后第三位继续
    void exchange(int* num1,int* num2) {
        int num = *num1;
        *num1 = *num2;
        *num2 = num;
    }
    int removeDuplicates(int* nums, int numsSize){
        if(numsSize < 2)
            return numsSize;
        for(int now = 1,last_find = 1;;now++) {//当前位置
            for(int find = last_find;;find++) {//寻找的指针
                if(find >= numsSize)//查找结束
                    return now;
                if(nums[find] > nums[now-1]) {//找到指定元素
                    if(find != now)
                        exchange(nums+now,nums+find);
                    last_find = find + 1;//下次查找从下一个开始
                    break;
                }
            }
        }
    }
    
    • 这次的效率就比之前的高了很多很多,每一次的交换位置都是必要的
  • 相关阅读:
    poj 2676 Suduku (dfs)
    poj 1562 Oil Deposits (dfs)
    poj 2907 Collecting Beepers (dfs)
    poj 1655 Balancing Act (树形dfs)
    poj 3411 Paid Roads (dfs)
    hdu 2896 病毒侵袭 (AC)
    hdu 3065 病毒侵袭持续中 (AC)
    poj 2251 Dungeon Master (bfs)
    java中debug使用
    Swing入门级小项目总结
  • 原文地址:https://www.cnblogs.com/ekkone/p/11667170.html
Copyright © 2011-2022 走看看