import java.util.*; /** * Reverse bits of a given 32 bits <strong>unsigned</strong> integer. * * Example: * input 43261596, represented in binary as 00000010100101000001111010011100 * return 964176192, represented in binary as 00111001011110000010100101000000 * * Follow up: * If this function is <strong>called many times</strong>, how would you * optimize it? * * Answer: * Cache result for each bytes. * * Related problem: Reverse Integer * * Tags: Bit Manipulation */ class ReverseBits { public static void main(String[] args) { ReverseBits r = new ReverseBits(); int a = 43261596; System.out.println(r.reverseBits(a)); System.out.println(r.reverseBitsOpt(a)); int b = 1; System.out.println(r.reverseBits(b)); System.out.println(r.reverseBitsOpt(b)); } /** * O(1) Time, O(1) Space * Move res 1 bit left, a * Get first bit of n, b * res = a ^ b * Move n right 1 bit for next loop * Unsigned shift means fill new bit at the left with 0 instead of 1 */ public int reverseBits(int n) { int res = 0; // concat n's ith digit with res for (int i = 0; i < 32; i++) res = (res << 1) ^ ((n >>> i) & 1); return res; } private Map<Byte, Integer> cache = new HashMap<Byte, Integer>(); /** * O(1) Time, O(1) Space * Divide 32 bits into 4 bytes * Cache each byte and its reversed result in a hashmap * Check cache for result first instead of computing all */ public int reverseBitsOpt(int n) { byte[] bytes = new byte[4]; for (int i = 0; i < 4; i++) bytes[i] = (byte)((n >>> 8 * i) & 0xFF); int res = 0; for (int i = 0; i < 4; i++) res = (res << 8) ^ reverseBytes(bytes[i]); return res; } public int reverseBytes(byte b) { if (cache.containsKey(b)) return cache.get(b); int res = 0; for (int i = 0; i < 8; i++) { res = (res << 1) ^ ((b >>> i) & 1); } cache.put(b, res); return res; } }