[LeetCode交错正负数] | 刷题打卡

1,028 阅读2分钟

[LeetCode交错正负数] | 刷题打卡

一直有刷题习惯,最近才看到掘金举办了刷题活动,特来参加!此题为第11题。不得不说掘金的主题就是漂亮呀!赞。

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

交错正负数

描述 给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。

不需要保持正整数或者负整数原来的顺序。

样例 样例 1

输入 : [-1, -2, -3, 4, 5, 6]
输出 : [-1, 5, -2, 4, -3, 6]
解释 : 或者任何满足条件的答案 

挑战

完成题目,且不消耗额外的空间。

二、思路分析:

划分不可避免循环两次,所以时间复杂度是n2n^2

方法
描述
时间复杂度
空间复杂度
双指针法划分法,根据正负分类O(n2)O(n^2)(1)(1)
双指针法数量多的一类移动到后半部分O(n2)O(n^2)(1)(1)
双指针法指针分别+=2-=2O(n2)O(n^2)(1)(1)

三、AC 代码:

import java.util.Arrays;

public class SolutionI {

    public static void main(String[] args) {
        int[] nums = new int[] { -1, -2, -3, 4, 5, 6 };
        System.out.print(Arrays.toString(nums));
        rerange(nums);
        System.out.print(Arrays.toString(nums));
    }

    public static void rerange(int[] nums) {
        // count positive and negative
        int pos = 0;
        int neg = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                pos++;
            } else {
                neg++;
            }
        }
        // why need partition
        partition(nums, pos > neg);
        // why need interleave
        interleave(nums, pos == neg);
    }

    /**
     * 
     * @param nums
     * @param hasSameLength
     */
    private static void interleave(int[] nums, boolean hasSameLength) {
        int left = 1;
        int right = nums.length - 1;
        // why need compare lenght
        if (hasSameLength) {
            right = nums.length - 2;
        }

        while (left < right) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;

            // rerange and space onte element
            left += 2;
            right -= 2;
        }
    }

    private static void partition(int[] nums, boolean startPositive) {
        // why need pivot
        int pivot = startPositive ? 1 : -1;
        int left = 0;
        int right = nums.length - 1;

        while (left <= right) {
            while (left <= right && nums[left] * pivot > 0) {
                left++;
            }
            while (left <= right && nums[right] * pivot < 0) {
                right--;
            }

            if (left <= right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
                right--;
            }
        }
    }

}

四、总结:

题目收获:

  1. 此题虽然可以归类为双指针即相向双指针类问题
  2. 也可以归为划分算法类问题,因为要使用一次partition算法,将正数负数数量多的一方移动到后半部分
  3. 严格意义上来说,也属于计数类问题,因为在划分之前,要统计正数负数的数量,比较谁的数量多
  4. 直观上看它属于双指针的变种,即前面11道题目,leftright变化量都为1,此次变化量为+2,以此类推,双指针的变化量并不是固定的.