数组内元素移动

一、同一个数组里的移动

两种相对条件下的数组内元素移位

1、奇数在前,偶数在后。

//采用冒泡实现该算法,时间复杂度O(N2),空间复杂度O(n1),设置优化flag位。
	public static void main(String[] args) {
        int[] nums = new int[]{9,9,14,1,2,7,12,8,14,20};
        int n = nums.length;
        int l = 0, r = l + 1;
        while (l < n){
            if(nums[l]%2 == 0){
                while (r < n){
                    if (nums[r]%2 != 0){
                          //优化 采用循环前移降低时间复杂度
//                        flip(nums,l,r);
//                        flip(nums, l+1,r);
                        for (int i = r; i > l; i--) {
                            swap(nums, i-1, i);
                        }
                        l++;
                    }
                    r++;
                }
                break;
            }
            l++;
            r++;
        }
    }
    public static void swap(int[] nums, int l, int r){
        int t = 0;
        t = nums[l];
        nums[l] = nums[r];
        nums[r] = t;
    }

2、0在前,1在后

//采用直接置位,复杂度均为O1
public static int[] remove0(int[] nums){
        int n = nums.length;
        int l = n-1, r = n-1;
        while (l >= 0){
            if(nums[r] == 0){
                while (l > 0){
                    l--;
                    if(nums[l] != 0){
                        nums[r] = nums[l];
                        r--;
                    }
                }
                break;
            }
            l--;
            r--;
        }

        for (int i = 0; i <= r; i++) {
            nums[i] = 0;
        }
        return nums;
    }

3、数字在前,字母在后 (招银一面)

public static String removeChacters(String string){
        char[] chars = string.toCharArray();
        int n = chars.length;
        int l = 0, r = l+1;
        while (l < n)
        {
            if(!Character.isDigit(chars[l])){
                while (r < n){
                    if(Character.isDigit(chars[r])){
                        for (int i = r; i > l; i--) {
                            swap(chars, i, i-1);
                        }
                        l++;
                    }
                    r++;
                }
                break;
            }
            l++;
            r++;
        }
        return chars.toString();
    }
    public static void swap(char[] chars, int i, int j){
        char temp = ' ';
        temp =chars[i];
        chars[i] = chars[j];
        chars[j] = temp;
    }

移动数组内元素,条件a在前,条件b在后,且保持元素间相对位置不变。

4、时间复杂度优化:将一个数循环移位的优化

public static void moveKplace(int[] nums, int k){
        int n = nums.length;
        k = k % n;
        flip(nums,0, nums.length-1);
        flip(nums, n - k, nums.length-1);
    }
    public static void flip(int[] nums,int i, int j){
        while (i < j){
            swap(nums, i, j);
            i++;
            j--;
        }
    }

数组内关于重复元素的操作

1、找不重复数(无序约束)

针对一个数组中,只有一个不重复数

public static int singleNumber(int[] nums){
        int n = nums.length;
        Arrays.sort(nums);
        int l = 0, r = l+1;
        while (r < n){
            if(nums[l] == nums[r]){
                while (r < n && nums[r] == nums[l])
                    r++;
            }
            if(r-l == 1){
                return nums[l];
            }
            else {
                l = r;
                r += 1;
            }
        }
        if(l >= n)
            return -1;
        else
            return nums[l];
    }

1.2 找第一个不重复数、字符

public static char firstUniqChar(String s) {
        int n = s.length();
        if(n == 0) return ' ';
        char[] nums = s.toCharArray();
        if(n == 1) return nums[0];
        HashMap<Character, Integer> map = new HashMap<>();
        for(int i = 0; i<n;i++){
            map.put(nums[i], map.getOrDefault(nums[i], 0)+1);
        }
        for(int i = 0; i< n;i++){
            if(map.get(nums[i]) == 1)
                return nums[i];
        }
        return ' ';
    }

2、消除重复元素

针对于数组内只有一个不重复数字!(代码存疑!!!!)

public static void removeRepeat(int[] nums){
        int n = nums.length;
        Arrays.sort(nums);
        int l = 0, r = l+1, index = 1;
        while (r < n){
            if(nums[l] == nums[r]){
                while (r < n && nums[r] == nums[l])
                    r++;
                if(r < n){
                    nums[index] = nums[r];
                    index++;
                }
                else
                    break;
            }
            l = r;
            r += 1;
        }
        for (int i = index; i < n; i++) {
            nums[i] = 0;
        }
    }
2.1 消除重复数(重复数字只保留一个)

相当于python中list(set(list))函数

public static int[] singleNumbers(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        int l = 0;
        for (int i = 1; i < n; i++) {
            if(nums[l] != nums[i]){
                l++;
                nums[l] = nums[i];
            }
        }
        int len = l+1;
        int[] num = new int[l+1];
        for (int i = 0; i < l+1; i++) {
            num[i] = nums[i];
        }
         return num;
    }
2.2 消除重复数(只保留两个不重复只出现一次的数字)
int ret = 0;
        for (int n : nums) {
            ret ^= n;
        }
        int div = 1;
        while ((div & ret) == 0) {
            div <<= 1;
        }
        int a = 0, b = 0;
        for (int n : nums) {
            if ((div & n) != 0) {
                a ^= n;
            } else {
                b ^= n;
            }
        }
        return new int[]{a, b};

3、找众数

如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为n/2的元素(下标从 0 开始)一定是众数。

public static int majorityElement(int[] nums){
        Arrays.sort(nums);
        int n = nums.length;
        return nums[n/2];
    }

二、两个数组移动为一个

两个有序数组合并为一个有序数组

1、合并两个有序数组到第一个无限大的数组之中,且保持有序

public static void moveTonums(int m, int n, int[] nums1, int[] nums2){
        int k = nums1.length - 1;
        int l1 = m-1, l2 = n-1;
        while (l1 >= 0 && l2 >= 0){
            if(nums1[l1] > nums2[l2]){
                nums1[k] = nums1[l1];
                l1--;
            }
            else if(nums1[l1] < nums2[l2]){
                nums1[k] = nums2[l2];
                l2--;
            }
            k--;
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值