number问题

Missing Number

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

解法:从1到n求和,然后依次减去数组中各元素,所得即为缺失的数。

Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

解法:两个相同的数异或为0, 某个数与0异或结果即为该数。

Single Number II

Given an array of integers, every element appears three times except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

 解法一:根据在特定位上为1的元素个数对3取余是否非零,逐位判断单数在特定位上是否为1。将3改为其他整数可将算法推广。

public class Solution {
    public int singleNumber(int[] nums) {
        if (nums.length == 0) {
            return -1;
        }
        int result = 0;
        for (int i = 0; i < 32; i++) {
            int count = 0;
            int d = 1 << i;
            for (int j = 0; j < nums.length; j++) {
                if ((nums[j] & d) != 0) {
                    count++;
                }
            }
            if (count % 3 != 0) {
                result |= d;
            }
        }
        return result;
    }
}

解法二:

可以使用掩码变量:

  1. ones    代表第i th 位只出现一次的掩码变量
  2. twos   代表第i th 位只出现两次次的掩码变量
  3. threes   代表第i th 位只出现三次的掩码变量

当第 i th 位出现3次时,就 ones   和 twos   的第 i th 位设置为0. 最终的答案就是 ones。

public class Solution {
    public int singleNumber(int[] nums) {
        if (nums.length == 0) {
            return -1;
        }
        int ones = 0, twos = 0, threes = 0;
        for (int i = 0; i < nums.length; i++) {
            twos |= ones & nums[i];
            ones ^= nums[i];
            threes = ones & twos;
            ones &= ~threes;
            twos &= ~threes;
        }
        return ones;
    }
}

 

Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

解法:先遍历数组进行异或,得到异或结果。然后找出异或结果的最低位,将最低位跟数组元素进行与运算,根据结果是否为零将数组分为两部分,而两个数分别分布在这两部分中。在每个部分内分别进行异或,即可得到两个数。

public class Solution {
    public int[] singleNumber(int[] nums) {
        if (nums.length == 0 || nums.length == 1) {
            return null;
        }
        int xor = 0;
        for (int i = 0; i < nums.length; i++) {
            xor ^= nums[i];
        }
        int lowbit = xor & (-xor);
        int rst1 = 0;
        int rst2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if ((nums[i] & lowbit) == 0) {
                rst1 ^= nums[i];
            } else {
                rst2 ^= nums[i];
            }
        }
        int[] result = {rst1, rst2};
        return result;
    }
}

 

Majority Element

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

解法一:

public class Solution {
    public int majorityElement(int[] num) {
        if(num.length==1){
            return num[0];
        }
 
        Arrays.sort(num);
 
        int prev=num[0];
        int count=1;
        for(int i=1; i<num.length; i++){
            if(num[i] == prev){
                count++;
                if(count > num.length/2) return num[i];
            }else{
                count=1;
                prev = num[i];
            }
        }
 
        return 0;
    }
}

 

解法二:

public int majorityElement(int[] num) {
    if (num.length == 1) {
        return num[0];
    }
 
    Arrays.sort(num);
    return num[num.length / 2];
}

 

解法三:

public int majorityElement(int[] nums) {
    int result = 0, count = 0;
 
    for(int i = 0; i<nums.length; i++ ) {
        if(count == 0){
            result = nums[i];
            count = 1;
        }else if(result == nums[i]){
           count++;
        }else{
           count--;
        }
    }
 
    return result;
}

 

Majority Element II

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

解法:设置两个选举数,经过一次遍历选出出现频率最大的两个数,再进行一次遍历判断它们的出现次数是否大于⌊ n/3 ⌋

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> result = new ArrayList<Integer>();
        int r1 = 0;
        int r2 = 0;
        int count1 = 0;
        int count2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (r1 == nums[i]) {
                count1++;
            } else if (r2 == nums[i]) {
                count2++;
            } else if (count1 == 0) {
                r1 = nums[i];
                count1 = 1;
            } else if (count2 == 0) {
                r2 = nums[i];
                count2 = 1;
            } else {
                count1--;
                count2--;
            }
        }
        count1 = 0;
        count2 = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == r1) {
                count1++;
            } else if (nums[i] == r2) {
                count2++;
            }
        }
        if (count1 > nums.length / 3) {
            result.add(r1);
        }
        if (count2 > nums.length / 3) {
            result.add(r2);
        }
        return result;
    }
}

注意:选举过程中判断某个元素是否跟两个当前选举数相等和两个count数是否为零的先后顺序不能颠倒。

譬如改为:

        for (int i = 0; i < nums.length; i++) {
            if (count1 == 0) {
                r1 = nums[i];
                count1 = 1;
            } else if (r1 == nums[i]) {
                count1++;
            } else if (count2 == 0) {
                r2 = nums[i];
                count2 = 1;
            } else if (r2 == nums[i]) {
                count2++;
            } else {
                count1--;
                count2--;
            }
        }

此段在leetcode上会通过,但是事实上当数组输入为[1,2,2,3,2,2,4,5,6,7]时,在eclipse中输出结果为[]。而正确结果应该为[2].

 

posted on 2015-11-23 20:48  ShinningWu  阅读(190)  评论(0编辑  收藏  举报

导航