算法通关村--第三关数组白银挑战

一、删除元素问题

我认为删除数组中的元素可以分为两步,第一步是寻找需要删除的元素(可以是多个),第二步是将找到的应该被删除的元素之后的元素前移。那么需要前移多少位呢?设置一个int move_step=0;用于记录每个元素需要前移的位数,在数组遍历中,每当找到一个需要删除的元素的时候move_step++;这样对元素访问的时候就知道应该前移几步了。

    public int removeElement(int[] nums, int val) {
        if(nums.length==1&&nums[0]==val||nums.length==0)
            return 0;
        int front=1;
        int rear=0;
        int move_step=0;
        int length=nums.length;
        while(rear<nums.length){
            if(val==nums[rear]){//寻找需要删除的元素
                move_step++;
                rear++;
                length--;
            }
            else{//元素访问操作,将元素前移“move_step”位,在未找到删除元素之前,move_step值为零相当于原地不动。
                nums[rear-move_step]=nums[rear];
                rear++;
            }
        }
        return length;
    }
    public int removeDuplicates(int[] nums) {
        if(nums.length==0)
            return 0;
        if(nums.length==1)
            return 1;
        int front=1;
        int rear=0;
        int length=nums.length;
        int move_step=0;
        while(front<nums.length){
            if(nums[rear]==nums[front]){//寻找需要删除的元素
                move_step+=1;
                length=length-1;
            }
            else{//元素前移“move_step”个位置
                nums[front-move_step]=nums[front];
            }
                rear++;
                front++;            
        }
        return length;
    }

二、元素奇偶移动

 

双指针思想,两个指针,一个int left=0;一个int right=nums.length-1;将右边的偶数换到左边,把左边的奇数换到右边。

    public int[] sortArrayByParity(int[] nums) {
        if(nums.length==0)
            return nums;
        int left=0;
        int right=nums.length-1;
        while(left<right){
            if(nums[left]%2!=0){//如果left指向奇数,那么得换!
                while((nums[right]%2!=0)&&(left<right))//从右边找一个偶数来换!
                    right--;
                int temp=nums[left];
                nums[left]=nums[right];
                nums[right]=temp;
            }
            else//是偶数那就看下一个
                left++;
        }
        return nums;
    }

 三、轮转数组

 这题涉及到离散数学的知识(王道书里见过),假设数组A是由子串‘a’和子串‘b’组成。即A=ab

由于子串a,b的内容长度都不确定,那么不妨设A轮转后的数组B恰好能用 B=ba来表示

则 (ab)逆=b逆a逆  这个时候对于b逆 以及a逆 分别原地逆置就得到了 ba。

    public int[] reverse(int [] nums,int start,int end){
        while(start<end){
            int temp=nums[start];
            nums[start]=nums[end];
            nums[end]=temp;
            start++;
            end--;
        }
        return nums;
    }
    public void rotate(int[] nums, int k) {
        int len=nums.length;
        nums=reverse(nums,0,nums.length-1);
        nums=reverse(nums,0,k%len-1);
        nums=reverse(nums,k%len,len-1);            
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值