LeetCode题目记录

数组类:

1.原地去除数组中重复的元素

/**方法1 申请一个和nums大小一样的数组tmpNums,
     * 然后遍历nums中的元素,对每个元素判断是否在tmpNums出现过,
     * 如果出现过,那么就不放到新数组里面,也就是不做处理;
     * 如果没有出现过,那么就把它放到新的数组里面
     * 这种方法数组原来的相对顺序可以保证
     * 时间复杂度是n^2和空间复杂度是n
     */
public int removeDuplicates(int[] nums){
    if(nums.length==0) return 0;
    int[] tmpNums=new int[nums.length];
    tmpNums[0]=nums[0];
    int index=1;
    for(int i=0;i<nums.length;i++)
    {
        int j=0;
        for(;j<index;j++)
        {
            if(tmpNums[j]==nums[i]) break;
            
        }
        if(j==index)
       {
          tmpNums[index++]=nums[j];
       }
        
    }
    nums=tmpNums;
    return nums;
}
 /**
     * 方法2 先对nums排序,排序后重复的元素一定相邻
     * 然后遍历nums,并用index来表示不重复的元素应该存放的下标
     * 如果当前遍历的元素和它的前一个元素相等,那么它是重复的,遍历下一个
     * 如果不等,说明不重复,那么当前元素存放到数组中下标为index的地方,index++
     * 这样遍历下来,不同元素都放到原数组的前面去了
     * 采用这种方法,得到的是有序数组,数组原来的位置改变了
     * 时间和空间复杂度是对应排序算法的复杂度
     */
    public int removeDuplicates(int[] nums){
        if (nums.length == 0) { return 0; }
        Arrays.sort(nums);
        int index = 1;
        for (int i = 1, len=nums.length; i < len; i++){
            if (nums[i] != nums[i-1]){
                nums[index++] = nums[i];
            }
        }
        return index;
    }
/**
     * 方法3 利用直接插入排序的思想,将数组分成两部分
     * 左边认为是满足要求的不重复的部分,初始为1个元素nums[0]
     * 右边是等待遍历的部分,不断遍历右边的元素
     * 同样是index来表示左边部分不重复的元素应该存放的下标
     * 对于当前遍历的元素,通过第二层循环遍历左边部分0到index的元素
     * 如果有元素和当前元素相等,说明是重复的,那么不处理
     * 否则,说明不重复,那么插入到下标index的地方,index++
     * 采用这种方法,数组的相对顺序得到保证
     * 此方法是对方法1的改进
     * 时间复杂度为n^2,空间复杂度为1
     * @param nums
     * @return
     */
    public int removeDuplicates(int[] nums){
        if (nums.length == 0) return 0;
        int index = 1;//标记没有重复的位置的指针
        for (int i = 1, len = nums.length; i < len; i++){
            int j = 0;
            for(; j < index; j++){
            //判断当前遍历的第i个元素在index指针之前不重复的元素中是否出现过
                if (nums[j] == nums[i]) {
                    break;
                }
            }
            //替换已重复元素
            if(j == index) {
                nums[index++] = nums[i];
            }
        }
        return index;
    }
/**
     * 方法4 利用Java容器来帮助判断元素是否重复,可以使用Set Map List等
     * 这里可以利用Set容器不能存放相同元素的特性
     * 用index来表示不重复的元素应该存放的下标
     * 如果当前元素可以成功加入到Set容器中,说明这个元素没有重复
     * 那么当前元素就可以放到下标index的地方,index++
     * 如果add失败,说明元素重复,不做操作
     * 此方法同样是把不重复的数组放到数组的前面,并可以保证元素的相对位置不变,不过需要额外的Set容器空间
     * 时间复杂度n,空间复杂度n
     * @param nums
     * @return
     */
    public int removeDuplicates(int[] nums){
        if (nums.length == 0) return 0;
        Set<Integer> set = new HashSet<Integer>();
        int index = 0;
        for (int i = 0, len = nums.length; i < len; i++) {
            if(set.add(nums[i])) {
                nums[index++] = nums[i];
            }
        }
        return index;
    }

2.旋转数组

 /**
    *思路1:利用temp存储nums[nums.length-1]的值,依次将元素右移一位,重复k次
    */
    public void rotate(int[] nums, int k) {
        int len = nums.length;
        if(len == 0||(k%=len) == 0) {return;}
        for(int i=1;i<=k;i++){
            int temp=nums[len-1];
            for(int j=len-2;j>=0;j--){
                nums[j+1]=nums[j];
            }
            nums[0]=temp;
        }
        return;
    }

 /**
     * 思路2:旋转后元素nums[i]的位置为(i+k)% nums.length
     * 1.新建一个同样长度大小的tempnums[]
     * 2.若想空间复杂度为O(1),可进行原地置换
     */
        public void rotate(int[] nums, int k) {
            int len = nums.length;
            if(len == 0||(k%=len) == 0) {return;}
            int[] tempnums=new int[len];
            for(int i=0;i<len;i++){
                tempnums[i]=nums[i];
            }
            for(int i=0;i<len;i++){
                nums[(i+k)%len]=tempnums[i];
            }
            return;
        }
/**
 * 思路3:先反转前n-k个元素,再反转后k个元素,然后再将整个数组反转,反转的实现即首尾两个数字交换
 */
    public void rotate(int[] nums, int k) {
        int len = nums.length;
        if(len == 0||(k%=len) == 0) {return;}
        reverse(nums,0,len-k-1);
        reverse(nums,len-k,len-1);
        reverse(nums,0,len-1);
    }
    public static void reverse(int nums[],int start,int end){
        int temp;
        while(start<end && start>=0){
            temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值