Leetcode 27. Remove Element

最近在重新学习一下数据结构与算法的知识点, 只有将知识运用起来才能更好地掌握知识, 所以在学习了有关数组的知识之后, 在 LeetCode 上选择 tag 为 Array 的相关题目来学习一下, 在这里记录一下.

本题为 easy 难度的 Remove Element : 题目意思很容易理解, 就是在不分配额外内存的情况下, 将数组中非选定的元素放到数组的前面, 返回数组中非选定元素的长度, 返回数组的顺序可以是随意的. 

思路 1 : 很容易联想到在排序中, 前后两个指针, 交换数组位置的做法.

头指针指向第一个元素, 尾指针指向最后一个元素. 

class Solution {
    public int removeElement(int[] nums, int val) {
        if(nums.length <= 0)
            return 0;
        if(nums.length == 1) {
            if(val == nums[0])
                return 0;
            else
                return 1;
        }
        int first = 0;
        int last = nums.length - 1;
        while(first < last) {
            while(nums[last] == val && last > first)
                last--;
            while(nums[first] != val && first < last)
                first++;
            swap(nums, first, last);
            first++;
            last--;
        }
        return ++last;
    }
    
    public void swap(int[] nums, int p, int q) {
        int temp = nums[p];
        nums[p] = nums[q];
        nums[q] = temp;
    }
}

上面的代码是不能 AC 的. 分析一下错误, 首先, 交换数组两个元素之后, first ++ 和 last -- 是没有必要的, 在前面的两个 while 循环中可以处理该情况. 其次在三个 while 中都有 first < last 语句是冗余的, 在第一个 while 循环中可以用 if 来进行处理, 这样每走一步, 都进行了判断, 其实复杂度是差不多的.

class Solution {
    public int removeElement(int[] nums, int val) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int first = 0;
        int last = nums.length - 1;
        while(first <= last) {
            if(nums[first] != val)
                first++;
            else if(nums[last] == val)
                last--;
            else {
                int temp = nums[first];
                nums[first] = nums[last];
                nums[last] = temp;
            }
        }
        return first;
    }
}

一个比较大的疑惑在于 first <= last , 当 first 和 last 相等的时候应该就结束循环了, 为什么还要加上 = 号.

 

思路二 : 因为对数组的顺序没有要求, 所以可以只记录不是给定元素的数组元素.

class Solution {
    public int removeElement(int[] nums, int val) {
        int current = 0;
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] != val) {
                nums[current] = nums[i];
                current ++;
            }
        }
        return current;
    }
}

相比而言, 前面的两个指针的方法在时间复杂度上没有什么提升, 所以推荐使用这个方法.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值