九章算法题解记录【九】其他高频题

本文深入讲解了多种经典算法问题的解决方法,包括单例数字、多数数字、股票买卖最佳时机等,通过具体实例剖析了算法背后的逻辑思维和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SingleNumber
1 Single Number http://lintcode.com/zh-cn/problem/single-number/

public class Solution {
    /**
     * @param A: An integer array
     * @return: An integer
     */
    public int singleNumber(int[] A) {
        int res = 0;
        if (A == null || A.length == 0) {
            return res;
        }
        for (int i = 0; i < A.length; i++) {
            res ^= A[i];
        }
        return res;
    }
}

异或大法。

2 Single Number II http://www.lintcode.com/en/problem/single-number-ii/

public class Solution {
    public int singleNumberII(int[] A) {
        if (A == null || A.length == 0) {
            return -1;
        }
        int result=0;
        int[] bits=new int[32];
        for (int i = 0; i < 32; i++) {
            for(int j = 0; j < A.length; j++) {
                bits[i] += A[j] >> i & 1;
                bits[i] %= 3;
            }
            result |= (bits[i] << i);
        }
        return result;
    }
}

解题思路:统计二进制每个位上1的个数并对3取模。
出现一次的数字对应位上的1会被统计出来。

3 Single Number III http://www.lintcode.com/en/problem/single-numbe-iii/

public class Solution {
    /**
     * @param A : An integer array
     * @return : Two integers
     */
    public List<Integer> singleNumberIII(int[] A) {
        int xor = 0;
        for (int i = 0; i < A.length; i++) {
            xor ^= A[i];
        }
        
        int lastBit = xor - (xor & (xor - 1));
        // int lastBit = xor & (-xor); // 两句一样的作用,只保留xor的最后一个1。
        int group0 = 0, group1 = 0;
        for (int i = 0; i < A.length; i++) {
            if ((lastBit & A[i]) == 0) {
                group0 ^= A[i];
            } else {
                group1 ^= A[i];
            }
        }
        
        ArrayList<Integer> result = new ArrayList<Integer>();
        result.add(group0);
        result.add(group1);
        return result;
    }
}

利用异或运算。
假设两个落单数字是 A、B
2*n + 22∗n+2 个数字异或,会得到两个仅出现一次的数字的异或结果:xor = A^B。

其中我们取出xor中任何一位1,这里取最低位的1。
这个1一定是A和B中对应位上一个是1一个是0。
所以可以将所有数字分成两类,一类是该位是1的,一类是该位是0的。
分别异或起来就得到A和B了。两类数一定都是奇数个,多出来的一个分别就是A、B。

MajorityNumber
4 Majority Number http://lintcode.com/en/problem/majority-number/

public class Solution {
    /*
     * @param nums: a list of integers
     * @return: find a  majority number
     */
    public int majorityNumber(List<Integer> nums) {
        if (nums == null || nums.size() == 0) {
            return 0;
        }
        int majorNumber = 0;
        int count = 0;
        for (Integer num : nums) {
            if (count == 0) {
                majorNumber = num;
                count ++;
            } else {
                if (majorNumber == num) {
                    count ++;
                } else {
                    count --;
                }
            }
        }
        return majorNumber;
    }
}

严格大于一半,最终数量肯定能使count>0 且major为自己。

5 Majority Number II http://lintcode.com/en/problem/majority-number-ii/
只可能有两个数大于1/3 摩尔投票法 Moore Voting
两个count和major 最后验证是否大于1/3

public class Solution {
    /**
     * @param nums: A list of integers
     * @return: The majority number that occurs more than 1/3
     */
    public int majorityNumber(ArrayList<Integer> nums) {
        // write your code
        if (nums == null || nums.size() == 0) {
            return -1;
        }
        
        int num1 = 0;
        int num2 = 0;
        int count1 = 0;
        int count2 = 0;
        for (int i = 0; i < nums.size(); i++) {
            int newNum = nums.get(i);
            if (count1 == 0) {
                num1 = newNum;
                count1++;
            } else if (num1 == newNum) {
                count1++;
            } else if (count2 == 0) {
                num2 = newNum;
                count2++;
            } else if (num2 == newNum) {
                count2++;
            } else {
                count1--;
                count2--;
            }
        }
        
        count1 = 0;
        count2 = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums.get(i) == num1) {
                count1++;
            }
            
            if (nums.get(i) == num2) {
                count2++;
            }
        }
        
        return count1 > count2 ? num1 : num2;
    }
}

6 Majority Number III http://lintcode.com/en/problem/majority-number-iii/

public int majorityNumber(List<Integer> nums, int k) {
        // write your code here
        int size = nums.size() / k;
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            if (map.containsKey(num)) {
                map.put(num, map.get(num) + 1);
            } else {
                map.put(num, 1);
            }
        }
        for (Integer num : map.keySet()) {
            if (map.get(num) > size){
                return num;
            }
        }
        return 0;
    }

上面常规空间复杂度O(n),可以优化为O(k)
还是摩尔投票法,但是用map来存这k个数字,中途假如count == 0 则移除这个key

public class Solution {
    /**
     * @param nums: A list of integers
     * @param k: As described
     * @return: The majority number
     */
    public int majorityNumber(ArrayList<Integer> nums, int k) {
        // count at most k keys.
        HashMap<Integer, Integer> counters = new HashMap<Integer, Integer>();
        for (Integer i : nums) {
            if (!counters.containsKey(i)) {
                counters.put(i, 1);
            } else {
                counters.put(i, counters.get(i) + 1);
            }
            
            if (counters.size() >= k) {
                removeKey(counters);
            }
        }
        
        // corner case
        if (counters.size() == 0) {
            return Integer.MIN_VALUE;
        }
        
        // recalculate counters
        for (Integer i : counters.keySet()) {
            counters.put(i, 0);
        }
        for (Integer i : nums) {
            if (counters.containsKey(i)) {
                counters.put(i, counters.get(i) + 1);
            }
        }
        
        // find the max key
        int maxCounter = 0, maxKey = 0;
        for (Integer i : counters.keySet()) {
            if (counters.get(i) > maxCounter) {
                maxCounter = counters.get(i);
                maxKey = i;
            }
        }
        
        return maxKey;
    }
    
    private void removeKey(HashMap<Integer, Integer> counters) {
        Set<Integer> keySet = counters.keySet();
        List<Integer> removeList = new ArrayList<>();
        for (Integer key : keySet) {
            counters.put(key, counters.get(key) - 1);
            if (counters.get(key) == 0) {
                removeList.add(key);
            }
        }
        for (Integer key : removeList) {
            counters.remove(key);
        }
    }
}

炒股问题

7 Best Time to Buy and Sell Stock http://www.lintcode.com/en/problem/best-time-to-buy-and-sell-stock/

public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) {
            return 0;
        }
        int max = 0;
        int temp = 0;
        for (int i = 1; i < prices.length; i++) {
            int profit = prices[i] - prices[i - 1];
            temp += profit;
            if (temp < 0) {
                temp = 0;
            }
            max = Math.max(max, temp);
        }
        return max;
    }

贪心,当区间总和小于0 则说明该区间不用保存。

8 Best Time to Buy and Sell Stock II http://www.lintcode.com/en/problem/best-time-to-buy-and-sell-stock-ii/

public class Solution {
    /**
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) {
            return 0;
        }
        int result = 0;
        for (int i = 1; i < prices.length; i++) {
            int profit = prices[i] - prices[i - 1];
            result += profit >= 0 ? profit : 0;
        }
        return result;
    }
}

所有递增区间

9 Best Time to Buy and Sell Stock III http://www.lintcode.com/en/problem/best-time-to-buy-and-sell-stock-iii/

10 Best Time to Buy and Sell Stock IV https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iv/
上述两题是一个问题,实际上都是DP

假设一共有 n 天, 那么这 n 天最多能够完成 n / 2 比交易, 也就是说, 当 k * 2 >= n 时, 就变成了 买卖股票的最佳时机 II, 反之, 我们可以作为动态规划问题解决:

定义:

globalbest[i][j] 表示前i天,至多进行j次交易时的最大获益
mustsell[i][j] 表示前i天,至多进行j次交易,并且第i天卖出手中的股票时的最大获益
状态转移:

mustsell[i][j] = max(globalbest[i - 1][j - 1], mustsell[i - 1][j]) + prices[i] - prices[i - 1]
globalbest[i][j] = max(globalbest[i - 1][j], mustsell[i][j])
边界: mustsell[0][i] = globalbest[0][i] = 0

优化: 滚动数组优化两个状态的空间至一维数组.
class Solution {
    /**
     * @param k:      An integer
     * @param prices: Given an integer array
     * @return: Maximum profit
     */
    public int maxProfit(int k, int[] prices) {
        // write your code here
        if (k == 0) {
            return 0;
        }
        if (k >= prices.length / 2) {
            int profit = 0;
            for (int i = 1; i < prices.length; i++) {
                if (prices[i] > prices[i - 1]) {
                    profit += prices[i] - prices[i - 1];
                }
            }
            return profit;
        }
        int n = prices.length;
        int[][] mustsell = new int[n + 1][n + 1]; // mustSell[i][j] 表示前i天,至多进行j次交易,第i天必须sell的最大获益
        int[][] globalbest = new int[n + 1][n + 1]; // globalbest[i][j] 表示前i天,至多进行j次交易,第i天可以不sell的最大获益

        mustsell[0][0] = globalbest[0][0] = 0;
        for (int i = 1; i <= k; i++) {
            mustsell[0][i] = globalbest[0][i] = 0;
        }

        for (int i = 1; i < n; i++) {
            int gainorlose = prices[i] - prices[i - 1];
            mustsell[i][0] = 0;
            for (int j = 1; j <= k; j++) {
                mustsell[i][j] = Math.max(globalbest[(i - 1)][j - 1] + gainorlose, mustsell[(i - 1)][j] + gainorlose);
                globalbest[i][j] = Math.max(globalbest[(i - 1)][j], mustsell[i][j]);
            }
        }
        return globalbest[(n - 1)][k];
    }
};

SubArray类问题

11 Subarray http://lintcode.com/en/problem/maximum-subarray/

12 Subarray II http://lintcode.com/en/problem/maximum-subarray-ii/

13 Subarray III http://lintcode.com/en/problem/maximum-subarray-iii/

14 MinimumSubarray http://lintcode.com/en/problem/minimum-subarray/

15 Maximum Subarray Difference http://lintcode.com/en/problem/maximum-subarray-difference/

16 subArray Sum http://www.lintcode.com/en/problem/subarray-sum/

17 SubArray Sum Closest http://www.lintcode.com/en/problem/subarray-sum-closest/

Ksum类问题

18 2-Sum https://www.lintcode.com/problem/two-sum/description

public class Solution {
    /**
     * @param numbers: An array of Integer
     * @param target: target = numbers[index1] + numbers[index2]
     * @return: [index1, index2] (index1 < index2)
     */
    public int[] twoSum(int[] numbers, int target) {
        if (numbers == null || numbers.length == 0) {
            return new int[]{-1, -1};
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < numbers.length; i++) {
            if (map.containsKey(numbers[i])) {
                if (i < map.get(numbers[i])) {
                    return new int[]{i, map.get(numbers[i])};
                } else {
                    return new int[]{map.get(numbers[i]), i};
                }
                
            } else {
                map.put(target - numbers[i], i);
            }
        }
        return new int[]{-1, -1};
    }
}

O(n) O(n) 但是这种方法很难改成ThreeSum及以上,因为很难去重(只能用Set)。改用双指针来做,因为要先sort,所以O(nlgn)

public class Solution {
    /*
     * @param numbers: An array of Integer
     * @param target: target = numbers[index1] + numbers[index2]
     * @return: [index1 + 1, index2 + 1] (index1 < index2)
     */
     class Pair {
         Integer value;
         Integer index;
         
         Pair(Integer value, Integer index) {
            this.value = value;
            this.index = index;
         }
         Integer getValue() {
             return this.value;
         }
     }

     class ValueComparator implements Comparator<Pair> {    
    
        @Override    
        public int compare(Pair o1, Pair o2) {    
            return o1.getValue().compareTo(o2.getValue());      
        }
     }
    public int[] twoSum(int[] numbers, int target) {
        // write your code here
        //用一个pair数组记录每个numbers[i]的值和它的位置i,防止排序后不知道该元素的位置
        Pair[] number = new Pair[numbers.length];
        for(int i=0;i<numbers.length;i++) {
            number[i] = new Pair(numbers[i], i);
        }
        //排序后使用双指针
        Arrays.sort(number, new ValueComparator());
        int L=0, R =  numbers.length-1;
        while(L<R) {
            if( number[L].getValue() + number[R].getValue() == target) {
                int t1 = number[L].index;
                int t2 = number[R].index;
                int[] result = {Math.min(t1,t2), Math.max(t1,t2)};
                return result;
            }
            if( number[L].getValue() + number[R].getValue() < target) {
                L++;
            } else {
                R--;
            }
        }
        int[] res = {};
        return res;
    }
}

用了一个Pair结构,为了保存排序后的下标。

19 3-Sum http://lintcode.com/en/problem/3sum/
twosum + set去重

public class Solution {
    /**
     * @param numbers: Give an array numbers of n integer
     * @return: Find all unique triplets in the array which gives the sum of zero.
     */
    public List<List<Integer>> threeSum(int[] numbers) {
        List<List<Integer>> res = new ArrayList<>();
        HashSet<List<Integer>> set = new HashSet<>();
        if (numbers == null || numbers.length == 0) {
            return res;
        }
        Arrays.sort(numbers);
        for (int i = 0; i < numbers.length; i++) {
            if (i != 0 && numbers[i] == numbers[i - 1]) {
                continue;
            }
            TwoSum(set, i + 1, 0 - numbers[i], numbers);
        }
        res.addAll(set);
        return res;
    }
    private void TwoSum(HashSet<List<Integer>> result,
                        int start,
                        int target,
                        int[] numbers){
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = start; i < numbers.length; i++) {
            if (map.containsKey(numbers[i])) {
                if (i > map.get(numbers[i])) {
                    result.add(Arrays.asList(numbers[start - 1], numbers[map.get(numbers[i])], numbers[i]));
                } else {
                    result.add(Arrays.asList(numbers[start - 1], numbers[i], numbers[map.get(numbers[i])]));
                }
            } else {
                map.put(target - numbers[i], i);
            }
        }
    }
   
}

ThreeSum 双指针法

public class Solution {
    /**
     * @param nums : Give an array numbers of n integer
     * @return : Find all unique triplets in the array which gives the sum of zero.
     */
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> results = new ArrayList<>();
        
        if (nums == null || nums.length < 3) {
            return results;
        }
        
        Arrays.sort(nums);

        for (int i = 0; i < nums.length - 2; i++) {
            // skip duplicate triples with the same first numebr
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            int left = i + 1, right = nums.length - 1;
            int target = -nums[i];
            
            twoSum(nums, left, right, target, results);
        }
        
        return results;
    }
    
    public void twoSum(int[] nums,
                       int left,
                       int right,
                       int target,
                       List<List<Integer>> results) {
        while (left < right) {
            if (nums[left] + nums[right] == target) {
                ArrayList<Integer> triple = new ArrayList<>();
                triple.add(-target);
                triple.add(nums[left]);
                triple.add(nums[right]);
                results.add(triple);
                
                left++;
                right--;
                // skip duplicate pairs with the same left
                while (left < right && nums[left] == nums[left - 1]) {
                    left++;
                }
                // skip duplicate pairs with the same right
                while (left < right && nums[right] == nums[right + 1]) {
                    right--;
                }
            } else if (nums[left] + nums[right] < target) {
                left++;
            } else {
                right--;
            }
        }
    }
}

20 3-Sum Closest https://www.lintcode.com/problem/3sum-closest/description

public class Solution {
    /**
     * @param numbers: Give an array numbers of n integer
     * @param target: An integer
     * @return: return the sum of the three integers, the sum closest target.
     */
    public int threeSumClosest(int[] numbers, int target) {
        int res = Integer.MAX_VALUE;
        if (numbers == null || numbers.length == 0) {
            return res;
        }
        Arrays.sort(numbers);
        for (int i = 0; i < (numbers.length - 2); i++) {
            if (i != 0 && numbers[i] == numbers[i - 1]) {
                continue;
            }
            int left = i + 1;
            int right = numbers.length - 1;
            while (left < right) {
                int sum = numbers[i] + numbers[left] + numbers[right];
                if (Math.abs(sum - target) < Math.abs(res - target)) {
                    res = sum;
                }
                if (sum == target) {
                    return target;
                } else if (sum < target) {
                    left ++;
                } else {
                    right --;
                }
            }
        }
        return res;
    }
}

双指针,没啥难度

21 4-Sum http://lintcode.com/en/problem/4sum/

public class Solution {
    public List<List<Integer>> fourSum(int[] numbers, int target) {
        List<List<Integer>> res = new ArrayList<>();
        if (numbers == null || numbers.length == 0) {
            return res;
        }
        Arrays.sort(numbers);
        for (int i = 0; i < numbers.length - 3; i++) {
            if (i != 0 && numbers[i] == numbers[i - 1]) {
                continue;
            }
            for (int j = i + 1; j < numbers.length - 2; j++) {
                if (j != (i + 1) && numbers[j] == numbers[j - 1]) {
                    continue;
                }
                int left = j + 1;
                int right = numbers.length - 1;
                while (left < right) {
                    int sum = numbers[i] + numbers[j] + numbers[left] + numbers[right];
                    if (sum == target) {
                        res.add(Arrays.asList(numbers[i], numbers[j], numbers[left], numbers[right]));
                        left++;
                        right--;
                        while (numbers[left] == numbers[left - 1]) {
                            left++;
                        }
                        while (numbers[right] == numbers[right + 1]) {
                            right++;
                        }
                    } else if (sum > target) {
                        right--;
                    } else {
                        left++;
                    }
                }
            }
        }
        return res;
    }
}

O(n3) TwoSum的套俩遍历版本,双指针法,找到了就left ++ right-- 并去重,找不到就动一下指针。

22 k-Sum http://www.lintcode.com/en/problem/k-sum/
三重背包,再做一遍

public class Solution {
    /**
     * @param A: An integer array
     * @param k: A positive integer (k <= length(A))
     * @param target: An integer
     * @return: An integer
     */
    public int kSum(int[] A, int k, int target) {
        // 错误输入条件
        if (A == null || A.length < k) {
            return 0;
        }
        int sum = 0;
        for (int i : A) {
            sum += i;
        }
        if (sum < target) {
            return 0;
        } else if (sum == target) {
            return 1;
        }
        // 状态定义 dp[i][j][t]表示从前i个物品里选出j个,和为t的最大方案个数
        int[][][] dp = new int[A.length + 1][k + 1][target + 1];

        // 初始化 dp[i][0][0]始终为1,因为全是正整数
        for (int i = 0; i < A.length + 1; i++) {
            dp[i][0][0] = 1;
        }

        // 递归求解
        for (int i = 1; i <= A.length ; i++) {
            for (int j = 1; j <= k && j <= i; j++) {
                for (int t = 0; t <= target; t++) {
                    if (A[i - 1] <= t) {
                        dp[i][j][t] = dp[i - 1][j][t] + dp[i - 1][j - 1][t - A[i - 1]];
                    } else {
                        dp[i][j][t] = dp[i - 1][j][t];
                    }
                }
            }
        }

        // 答案
        return dp[A.length][k][target];
    }
}

两个注意点,
1 最内层判断 t与A[i - 1]分别赋值,而不是直接从A[i - 1]开始,这样子没有继承前i-1个物品的状态。
2 j <= i 的同时要 <=k

Quick Questions
23 快速幂 http://www.lintcode.com/en/problem/fast-power/

public class FastPower {
    /**
     * @param a: A 32bit integer
     * @param b: A 32bit integer
     * @param n: A 32bit integer
     * @return: An integer
     */
    public int fastPower(int a, int b, int n) {
        if (n == 0){
            return 1 % b;
        } else if (a == 0) {
            return 0;
        } else if (n == 1) {
            return a % b;
        }

        long res = 1;
        long pow = a;
        while (n != 0) {
            if (n % 2 == 1) {
                res = (res * pow) % b;
            }
            pow = (pow * pow) % b;
            n /= 2;
        }
        return (int)(res % b);
    }
}

非递归写法,开始没A的原因是没用long

24 Sqrt(x) http://www.lintcode.com/en/problem/sqrtx/ Magic Number 0x5f3759df


public class SqrtX {
    /**
     * @param x: An integer
     * @return: The sqrt of x
     */
    public int sqrt(int x) {
        if (x < 0)  throw new IllegalArgumentException();
        else if (x <= 1)    return x;
        int start = 1, end = x;
        // 直接对答案可能存在的区间进行二分 => 二分答案
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            // writing in this way instead of "nums[mid] * nums[mid]" to avoid overflow
            if (mid == x / mid)  return mid;
                // possible root must be larger than or equal to current mid
            else if (mid < x / mid) start = mid;
                // possible root must be smaller than or equal to current mid
            else    end = mid;
        }
        if (end > x / end)  return start;
        return end;
    }
}

二分查找法。

25 Trailing Number of zeros in n! http://www.lintcode.com/en/problem/trailing-zeros/

class Solution {
    /*
     * param n: As desciption
     * return: An integer, denote the number of trailing zeros in n!
     */
    public long trailingZeros(long n) {
        long sum = 0;
        while (n != 0) {
            sum += n / 5;
            n /= 5;
        }
        return sum;
    }
};

蛮玄乎的,0的个数取决于5的个数。

26 O(1) Check Power of 2 http://www.lintcode.com/problem/o1-check-power-of-2/

class Solution {
    /*
     * @param n: An integer
     * @return: True or false
     */
    public boolean checkPowerOf2(int n) {
        if (n <= 0) {
            return false;
        }
        return (n & (n-1)) == 0;
    }
};

二进制中只有一个1 n&(n-1)作用:将n的二进制表示中的最低位为1的改为0

Partition

27 Partition Array http://lintcode.com/en/problem/partition-array/

public class Solution {
    /**
     * @param nums: The integer array you should partition
     * @param k: An integer
     * @return: The index after partition
     */
    public int partitionArray(int[] nums, int k) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int start = 0;
        int less = start - 1;
        int end = nums.length - 1;
        int more = end;
        while (start <= more) {
            if (nums[start] < k) {
                swap(nums, ++less, start++);
            } else if (nums[start] == k) {
                start ++;
            } else {
                swap(nums, more--, start);
            }
        }
        return less + 1;
    }

    private void swap(int[] A, int a, int b) {
        // 交换
        int temp = A[a];
        A[a] = A[b];
        A[b] = temp;
    }
}

通用Partition模板

28 Sort Letters by Case http://lintcode.com/en/problem/sort-letters-by-case/

public class Solution {
    /*
     * @param chars: The letter array you should sort by Case
     * @return: nothing
     */
    public void sortLetters(char[] chars) {
        if (chars == null || chars.length == 0) {
            return;
        }
        int start = 0;
        int end = chars.length - 1;
        while (start <= end) {
            if (chars[start] >= 'a' && chars[start] <= 'z') {
                start ++;
            } else {
                swap(chars, end--, start);
            }
        }
        return;
    }

    private void swap(char[] A, int a, int b) {
        // 交换
        char temp = A[a];
        A[a] = A[b];
        A[b] = temp;
    }
}

29 Sort Colors http://lintcode.com/zh-cn/problem/sort-colors/

public class Solution {
    public void sortColors(int[] nums) {
        if (nums == null || nums.length == 0) {
            return;
        }
        int start = 0;
        int less = start - 1;
        int end = nums.length - 1;
        while (start <= end) {
            if (nums[start] == 0) {
                swap(nums, ++less, start++);
            } else if (nums[start] == 1) {
                start++;
            } else {
                swap(nums, end--, start);
            }
        }
        return;
    }

    private void swap(int[] A, int a, int b) {
        // 交换
        int temp = A[a];
        A[a] = A[b];
        A[b] = temp;
    }
}

30 Interleaving Negative & Positive numbers http://lintcode.com/zh-cn/problem/interleaving-positive-and-negative-numbers/

class Solution {
    /**
     * @param A: An integer array.
     * @return: void
     */
    public int[] rerange(int[] A) {
        // Check the input parameter.
        if(A == null || A.length < 3)
            return A;
        
        int n = A.length;
        
        int countPositive = 0;//count the number of positive numbers
        
        
        
        // store the positive numbers index.
        int positiveIndex = 0;
        int pos = 1;
        int neg = 0;
        for(int i=0;i<n;i++) {
                if(A[i] > 0) {
                // Put all the positive numbers at in the left part.
                    swap(A,positiveIndex++,i);
                    countPositive++;
                }
        }
        
        if(countPositive > n/2) {
        // If positive numbers are more than negative numbers,
        // Put the positive numbers at first.
            pos = 0;
            neg = 1;
            // Reverse the array.
            
            int left = 0;
            int right = n-1;
            while(left < right) {
                swap(A,left,right);
                left++;
                right--;
            }
        }
        
        while(pos < n && neg <n) {
            while(pos<n && A[pos]>0)
                pos +=2;
            while(neg<n && A[neg]<0)
                neg +=2;
            if(neg >= n || pos>=n)
                break;
            swap(A,pos,neg);
        }
       return A; 
   }
   
   public void swap(int[] A, int l, int r) {
       int temp = A[l];
       A[l] = A[r];
       A[r] = temp;
   }
}

先判断正数多还是负数多。然后每次指针+2交换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值