題目1: 求一個int類型正整數二進制中最高位1的位置?
比如10,二進制位1010,最高位1所在位置位4。
解體思路:
- 使用高位擴散,將1010擴散位1111
- 使用二分法,計算32位二進制中1111前面0的位數n;
- 結果為32-n
代碼如下:
public static int getMaxDigit(int num) {// 獲取最高位為1的數,例如8會得到8(1000)int highestOneBit = Integer.highestOneBit(num);// 計算這個數的二進制位數return 32 - numberOfLeadingZeros2(highestOneBit);}public static int numberOfLeadingZeros2(int i) {int res = 1;// 看條件A:高16為是否都為0。// 如果是結果加16;并且將低16位變成高16位(這里是為了和條件A的反邏輯即高16位有不為0的情況進行統一)if (i >>> 16 == 0) {i <<= 16;res += 16;}// 看高8位是否都為0if( i >>> 24 == 0) {res += 8;i <<= 8;}// 看高4位是否都為0if (i >>> 28 == 0) {res += 4;i <<= 4;}// 看高2位是否都為0if (i >>> 30 == 0) {res += 2;i <<= 2;}// 看高一位是否為0,因為res的初始值為1return res - (i >>> 31);}
highestOneBit、numberOfLeadingZeros 這兩個方法都是Integer包裝類中的。
highestOneBit:求指定num的最高位為1,其他位為0的數字。實現邏輯如下:
public static int highestOneBit(int i) {// HD, Figure 3-1i |= (i >> 1);i |= (i >> 2);i |= (i >> 4);i |= (i >> 8);i |= (i >> 16);return i - (i >>> 1);}
用位移和或運算實現。
題目2: 給一個數字target,求數組和為target的全部組合,相同的組合只能出現一次。
輸入:target=8,nums=[2,1,5,1,6,7]
輸出:
[[1,1,6],
[1,2,5],
[1,7]]
思路:
1.排序
2.回溯
3.去重
public static void main(String[] args) {System.out.println(Arrays.deepToString(getCombineSum(8, new int[]{2,1,5,1,6,7}).toArray()));}public static List<List<Integer>> getCombineSum(int target, int[] nums) {Arrays.sort(nums);List<List<Integer>> res= new ArrayList<>(16);List<Integer> path = new ArrayList<>(16);hsSum(res, path, target, nums, 0);return res;}public static void hsSum(List<List<Integer>> res, List<Integer> path, int target, int[] nums, int begin) {if (target == 0) {res.add(new ArrayList<>(path));return;} else if (target < 0) {return;}for (int i = begin; i < nums.length; i++) {if (i > begin && nums[i - 1] == nums[i]) {continue;}path.add(nums[i]);hsSum(res, path, target - nums[i], nums,i + 1);path.remove(path.size()-1);}}