【位運算】B010_LC_字母組合迭代器(二進制枚舉)

一、Problem

Design an Iterator class, which has:

A constructor that takes a string characters of sorted distinct lowercase English letters and a number combinationLength as arguments.
A function next() that returns the next combination of length combinationLength in lexicographical order.
A function hasNext() that returns True if and only if there exists a next combination.

CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator.

iterator.next(); // returns "ab"
iterator.hasNext(); // returns true
iterator.next(); // returns "ac"
iterator.hasNext(); // returns true
iterator.next(); // returns "bc"
iterator.hasNext(); // returns false

Constraints:

1 <= combinationLength <= characters.length <= 15
There will be at most 10^4 function calls per test.
It’s guaranteed that all calls of the function next are valid.

二、Solution

方法一:二進制枚舉

最暴力的方法就是用回溯法所有組合預處理出來,但這裏寫一個比較新穎的做法:利用二進制位 1 來表示有字母需要選,0 表示該位置的字母不需要選。

class CombinationIterator {
	char[] alps;
	int n, len, tot;

    public CombinationIterator(String characters, int combinationLength) {
    	alps = characters.toCharArray();
    	n = alps.length;
    	len = combinationLength;
    	tot = (1 << n) - 1;  
    }

    public String next() {
        while (tot > 0 && countOne(tot) != len)
        	tot--;
        String res = b2s(tot);
        tot--;
        return res;
    }
    
    public boolean hasNext() {
        return tot >= (1 << len) - 1;
    }

    int countOne(int bits) {
    	int cnt = 0;
    	while (bits != 0) {
    		bits &= (bits - 1);
    		cnt++;
    	}
    	return cnt;
    }
    String b2s(int bits) {
    	StringBuilder sb = new StringBuilder();
    	int i = 0;
    	while (bits != 0) {
    		if ((bits & 1) == 1)
    			sb.append(alps[n-i-1]);
    		i++;
    		bits = bits >>> 1;
    	}
    	return sb.reverse().toString();
    }
}

複雜度分析

  • 時間複雜度:O(n×2n)O(n × 2^n)
  • 空間複雜度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章