[LeetCode] 3 remove element problems

来源:互联网 发布:淘宝保证金怎么缴纳 编辑:程序博客网 时间:2024/06/12 17:11

三道有关移除数组中某个数据的题目,拥有相似的解题思路。
依次来看一下。

第一题:
Remove Nth Node From End of List,移除一个链表中倒数第n个元素,难点在于要求一次遍历搞定。
正常思路,当然是先遍历到链表有多长,然后无论从头还是从尾,再多做一次遍历,删除那个节点,即可。
但是要符合一次遍历搞定的要求,我们要用两个标志位了。先把index走n个位置,然后item指针跟index一起++。这样,当index到尾的时候,index就停在倒数第n个上。考虑到链表的删除,还需要个pre,指向index.
代码如下:

public class Solution {    public ListNode removeNthFromEnd(ListNode head, int n) {        if(head == null){            return head;        }        ListNode pre = new ListNode(0);        ListNode item = head;        pre.next = item;        ListNode index = item;        //index先走n个位置        while(n>1){            index = index.next;            n--;        }        //index,item,pre同时开始移动        while(index.next!=null){            index = index.next;            item = item.next;            pre = pre.next;        }        //删除        if(pre.next == head){            return item.next;        }else{            pre.next = item.next;            return head;        }    }}

第二题:
Remove Duplicates from Sorted Array,从排序数组中删除重复的元素,要求不能有额外的空间。
暴力方法当然好解决,虽然java没有提供直接删除array里元素的方法,不过可以转成容器再删除。又或者,正常的遍历,复制到一个新数组就好了。但是这两种方法都要额外的内存空间。
观察一下,因为数组已经排序,所以,对于从i到i+m的重复数据,从i+1到i+m都是没用。因此,可以直接把i+m+1位置开始的数据往前挪动到i+1的位置,也就是挪动m位。
因此,用两个标志位,size标记着最后一个可用的挪动位置,i标记着循环正常走到的位置。实现一下,即可:

public class Solution {    public int removeDuplicates(int[] nums) {        int size = 0;        int i = 0;        int length = nums.length;        if(length < 2){            return length;        }        while(i<length){            if(i == length - 1){                nums[size] = nums[i];                size++;            }else if(nums[i] != nums[i+1]){                //往前挪动数据                nums[size] = nums[i];                size++;            }            i++;        }        return size;    }}

第三题:
Remove Element,对于乱序的数组,给定一个数值val,把数组中所有的val去除。
暴力解法,转容器,遍历一遍,一个个移除。或者直接遍历,然后复制出来。可惜是数组,不是链表,所以删除的时间效率堪忧。直接复制当然又有空间复杂度的问题。
结合上述两题,思路雷同,继续两个标记。
先排序一下。
然后用i找到val第一次出现的位置。
然后再用j找到val最后一次出现的位置。
最后,循环一下,把j+1后面的数全面往前挪j-i个位置。
搞定。

public class Solution {    public int removeElement(int[] nums, int val) {        if(nums.length <1){            return 0;        }        Arrays.sort(nums);        //找到val出现的位置        int i =0;        while(i<nums.length && nums[i] != val){            i++;        }        if(i == nums.length){            return nums.length;        }        //找到val结束的位置        int j = i;        while(j<nums.length && nums[j]== val){            j++;        }        if(j == nums.length){            return i;        }        //循环处理一下        for(int l = j, m =i;l<nums.length;l++, m++){            nums[m]=nums[l];        }        return i+nums.length-j;    }}
0 0
原创粉丝点击