Leetcode刷题比较—binary search (17)

528. Random Pick with Weight

class Solution:

    def __init__(self, w: List[int]):
        self.running_sums = []
        running_sum = 0
        for weight in w:
            running_sum += weight
            self.running_sums.append(running_sum)
        self.total_sum = running_sum
        

    def pickIndex(self) -> int:
        target = random.randint(1, self.total_sum)
        low, high = 0, len(self.running_sums)
        while low < high:
            mid = low + (high - low) // 2
            if target > self.running_sums[mid]:
                low = mid + 1
            else:
                high = mid
        return low

497. Random Point in Non-overlapping Rectangles

class Solution:

    def __init__(self, rects: List[List[int]]):
        self.rects = rects
        self.areas = []
        self.total_area = 0
        for rect in rects:
            x1, y1, x2, y2 = rect
            area = (x2 - x1 + 1) * (y2 - y1 + 1) 
            # x1 = 1,x2 = 3,矩形的宽度应该是包含从 x1 到 x2 的所有点,即 1、2、3 这三个 x 坐标。所以宽度是 3 - 1 + 1 = 3
            self.total_area += area
            self.areas.append(self.total_area)

        

    def pick(self) -> List[int]:
        target = random.randint(1, self.total_area)
        idx = bisect.bisect_left(self.areas, target)
        x1, y1, x2, y2 = self.rects[idx]
        x = random.randint(x1, x2)
        y = random.randint(y1, y2)
        return [x,y]

        '''
            计算每个矩形的面积:每个矩形的面积越大,被选择到的概率也应该越大。因此,我们首先要计算出每个矩形的面积,并且维护一个前缀和数组 areas,用来存储这些矩形面积的累加值。

    根据前缀和数组来选择矩形:我们可以使用一个随机数生成器来生成一个随机的整数,然后通过二分查找在前缀和数组中找到对应的矩形。

    在选中的矩形内随机选择一个点:一旦选定了一个矩形,我们可以在这个矩形的边界内随机选择一个点。
'''
    
        


# Your Solution object will be instantiated and called as such:
# obj = Solution(rects)
# param_1 = obj.pick()

33. Search in Rotated Sorted Array

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            if nums[left] <= nums[mid]:
                if nums[left] <= target < nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            if nums[mid] <= nums[right]:
                if nums[mid] < target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1
        return -1

81. Search in Rotated Sorted Array II

class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = (low + high) // 2
            if nums[mid] == target:
                return True

            if nums[low] == nums[mid]:
                low += 1
                continue
            
            if nums[low] <= nums[mid]:
                if nums[low] <= target <= nums[mid]:
                    high = mid - 1
                else:
                    low = mid + 1
            else:
                if nums[mid] <= target <= nums[high]:
                    low = mid + 1
                else:
                    high = mid - 1
          return False

        

375. Guess Number Higher or Lower II(dp

class Solution {
    int[][] best;
    public int getMoneyAmount(int n) {
        best = new int[n + 1][n + 1];
        for (int i = 0; i < n + 1; i++) {
            Arrays.fill(best[i], -1);
        }
        return dp(1, n);
    }
    
    private int dp(int lo, int hi) {
        if (lo >= hi) {
            return 0;
        } else {
            if (best[lo][hi] != -1) {
                return best[lo][hi];
            }
            //the idea is to  compute the maximum amount of money I need to pay with my guesses ranging from lo to hi.
            //Since I want to minimize my payoff, I'll choose the starting point [lo,hi] that has the minimum payoff.
            //But for each starting point, I'll choose the maximum amount of money I pay, since I need the worst case scenario.
            int res = Integer.MAX_VALUE;
            for (int i = lo; i <= hi; i++) {
                int op1 = 0; //guess = i, i was correct, no cost incurred
                int op2 = i + dp(lo, i - 1);//guess = i = wrong, go lo
                int op3 = i + dp(i + 1, hi);//guess = i = wrong, go hi
                int out = Math.max(op1, Math.max(op2, op3));
                res = Math.min(out, res);
            }
            best[lo][hi] = res;
            return res;
        }
    }       
}

374. Guess Number Higher or Lower

public class Solution extends GuessGame {
    public int guessNumber(int n) {
        int left = 1, right = n;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            int num = guess(mid);
            if(num == 0) {
                return mid;
            } else if(num == -1) {
                right = mid - 1;
            } else if(num == 1) {
                left = mid + 1;

            }
        }
        return -1;
    }
}

35. Search Insert Position

class Solution {
    public int searchInsert(int[] nums, int target) {
       int left = 0, right = nums.length - 1;
       while(left <= right) {
           int mid = left + (right - left) / 2;
               if(nums[mid] == target) {
                   return mid;
               } else if(nums[mid] < target) {
                   left = mid + 1;
               } else {
                   right = mid - 1;
               }
       } 
       return left;
    }
}

278. First Bad Version

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1, right = n;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if(isBadVersion(mid)) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

367. Valid Perfect Square

class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 1, right = num;
        while(left <= right) {
            int mid = left + (right - left) / 2;
            // mid * mid 会越界
            int div = num / mid;
            if(div == mid) {
                if(num % mid == 0) {
                    return true;
                }
                left = mid + 1;
            } else if(div < mid) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return false;
    }
}

69. Sqrt(x)

class Solution {
    public int mySqrt(int x) {
        int l = 1, r = x;
        while(l <= r) {
            int mid = l + (r - l) / 2;
            if((long) mid * mid == (long) x ) {
                return mid;
            } else if((long) mid * mid < (long) x) {
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return Math.round(r);
    }
}

441. Arranging Coins

class Solution {
    public int arrangeCoins(int n) {
        if(n < 0) {
            throw new IllegalArgumentException("only positve number allowed");
        }
        if(n <= 1) {
            return n;
        }
        if(n <= 3) {
            return n == 3 ? 2 : 1;
        }
        long left = 0, right = n / 2;
        while(left <= right) {
            long mid = left + (right - left) / 2;
            long sum = mid * (mid + 1) / 2;
            if(sum == n) {
                return (int)mid;
            } else if(sum < n) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return (int)right;
    }
}

34. Find First and Last Position of Element in Sorted Array

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        int[] ans = {-1, -1};
        while(left <= right) {
            int mid = left + (right - left) / 2;
            if(nums[mid] == target) {
                ans[0] = mid;
                right = mid - 1;
            } else if(nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        left = 0;
        right = nums.length - 1;
        while(left <= right) {
            int mid = left + right >> 1;
            if(target == nums[mid]) {
                ans[1] = mid;
                left = mid + 1;
            } else if(target < nums[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }
}

136. Single Number

class Solution {
    public int singleNumber(int[] nums) {
       for(int i = 1; i < nums.length; i++) {
           nums[0] ^= nums[i];
       }
       return nums[0];
    }
}

//异或运算:0 XOR 任何数等于任何数, 任何相同的二进制数进行XOR都等于0;

137. Single Number II

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer, Integer> map = new HashMap();
        for(int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
        for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if(entry.getValue() == 1) {
                return entry.getKey();
            }
        }
        return -1;
    }
}


class Solution {
    public int singleNumber(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length - 1;
        if (n == 0 || nums[0] != nums[1]) return nums[0];
        if (nums[n] != nums[n - 1]) return nums[n];
        for (int i = 1; i < n; i++) {
            if (nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) return nums[i];
        }
        return 0;
    }
}

540. Single Element in a Sorted Array

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int left = 0, right = nums.length - 1;
        while(left < right) {
            int mid = left + (right - left) / 2;
            if(mid % 2 == 1) {
                mid--;
            }
            if(nums[mid] == nums[mid + 1]) {
                left = mid + 2;
            } else {
                right = mid;
            }
        }
        return nums[left];
    }
}

275. H-Index II

class Solution {
    public int hIndex(int[] citations) {
        int left = 0, right = citations.length - 1, res = 0;
        while(left <= right) {
            int mid = (left + right) >> 1;
            int len = citations.length - mid;
            if(citations[mid] >= len) {
                res = len;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return res;
    }
}

1539. Kth Missing Positive Number

class Solution {
    public int findKthPositive(int[] arr, int k) {
        int left = 0, right = arr.length - 1;
        while(left <= right) {
            int mid = left + right >> 1;
            if(arr[mid] - mid - 1 < k) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return left + k;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值