2022.4.3 每日一题
给你一个排序后的字符列表 letters ,列表中只包含小写英文字母。另给出一个目标字母 target,请你寻找在这一有序列表里比目标字母大的最小字母。
在比较时,字母是依序循环出现的。举个例子:
如果目标字母 target = ‘z’ 并且字符列表为 letters = [‘a’, ‘b’],则答案返回 ‘a’
示例 1:
输入: letters = [“c”, “f”, “j”],target = “a”
输出: “c”
示例 2:
输入: letters = [“c”,“f”,“j”], target = “c”
输出: “f”
示例 3:
输入: letters = [“c”,“f”,“j”], target = “d”
输出: “f”
提示:
2 <= letters.length <= 10^4
letters[i] 是一个小写字母
letters 按非递减顺序排序
letters 最少包含两个不同的字母
target 是一个小写字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-smallest-letter-greater-than-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
//二分
int l = letters.length;
int left = 0;
int right = l - 1;
while(left < right){
int mid = (right - left) / 2 + left;
if(letters[mid] <= target){
left = mid + 1;
}else{
right = mid;
}
}
//如果找到头了,还没有找到比target大的
return letters[left] <= target ? letters[0] : letters[left];
}
}
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
left, right = 0, len(letters) - 1
while left < right:
mid = (int)((right - left) / 2 + left)
if letters[mid] <= target:
left = mid + 1
else:
right = mid
return letters[left] if letters[left] > target else letters[0]
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
return letters[r] if (r := bisect_right(letters, target)) < len(letters) else letters[0]
2022.4.4 每日一题
给你一个数组 nums ,请你完成两类查询。
实现 NumArray 类:
示例 1:
输入:
[“NumArray”, “sumRange”, “update”, “sumRange”]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]
解释:
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9
numArray.update(1, 2); // nums = [1,2,5]
numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
提示:
1 <= nums.length <= 3 * 10^4
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
调用 update 和 sumRange 方法次数不大于 3 * 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-mutable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
之前做过,也知道是树状数组,好久没写了,这里复习一下
首先掌握第一点,就是lowbit,取的是一个数二进制位中最小位置的1
然后第二点,明白树状数组的结构,这是理解树状数组的前提
树状数组中的数代表的是一个特定区间的和,而不是一个单独的数,所以说用树状数组计算会降低时间复杂度
两个操作,更新和查询都依赖lowbit,更新需要自底向上更新,查询需要从上至下查询
长度要比nums数组大1是因为,如果下标为0的话会进入死循环
class NumArray {
int[] tree;
public int lowbit(int x){
return x & (-x);
}
public void add(int x, int u){
for(int i = x; i <= n; i += lowbit(i))
tree[i] += u;
}
public int query(int x){
int res = 0;
for(int i = x; i > 0; i -= lowbit(i))
res += tree[i];
return res;
}
int[] nums;
int n;
public NumArray(int[] nums) {
this.nums = nums;
n = nums.length;
tree = new int[n + 1];
for(int i = 0; i < n; i++){
add(i + 1, nums[i]);
}
}
public void update(int index, int val) {
int diff = val - nums[index];
add(index + 1, diff);
nums[index] = val;
}
public int sumRange(int left, int right) {
return query(right + 1) - query(left);
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(index,val);
* int param_2 = obj.sumRange(left,right);
*/
class NumArray:
def __init__(self, nums: List[int]):
self.nums = nums
self.tree = [0] * (len(nums) + 1)
for i, num in enumerate(nums, 1):
self.add(i, num)
def lowbit(self, x : int) -> int:
return x & -x
def add(self, index : int, val : int):
while index <= len(self.nums):
self.tree[index] += val
index += self.lowbit(index)
def query(self, index : int) -> int:
ans = 0
while index:
ans += self.tree[index]
index -= self.lowbit(index)
return ans
def update(self, index: int, val: int) -> None:
self.add(index + 1, val - self.nums[index])
self.nums[index] = val
def sumRange(self, left: int, right: int) -> int:
return self.query(right + 1) - self.query(left)
# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(index,val)
# param_2 = obj.sumRange(left,right)
2022.4.5 每日一题
给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。
计算置位位数 就是二进制表示中 1 的个数。
示例 1:
输入:left = 6, right = 10
输出:4
解释:
6 -> 110 (2 个计算置位,2 是质数)
7 -> 111 (3 个计算置位,3 是质数)
9 -> 1001 (2 个计算置位,2 是质数)
10-> 1010 (2 个计算置位,2 是质数)
共计 4 个计算置位为质数的数字。
示例 2:
输入:left = 10, right = 15
输出:5
解释:
10 -> 1010 (2 个计算置位, 2 是质数)
11 -> 1011 (3 个计算置位, 3 是质数)
12 -> 1100 (2 个计算置位, 2 是质数)
13 -> 1101 (3 个计算置位, 3 是质数)
14 -> 1110 (3 个计算置位, 3 是质数)
15 -> 1111 (4 个计算置位, 4 不是质数)
共计 5 个计算置位为质数的数字。
提示:
1 <= left <= right <= 10^6
0 <= right - left <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/prime-number-of-set-bits-in-binary-representation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
两个点,一个是怎么统计1的个数,一个是怎么判断是不是质数
但是因为这里质数最大32,所以直接列出来就行了
统计1的个数用的bitCount
class Solution {
static int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
static Set<Integer> set;
static{
set = new HashSet<>();
for(int t : primes){
set.add(t);
}
}
public int countPrimeSetBits(int left, int right) {
int count = 0;
for(int i = left; i <= right; i++){
if(set.contains(Integer.bitCount(i)))
count++;
}
return count;
}
}
这个数组竟然要在class外面定义,需要好好研究一下python的语法了
PRIMES = {2,3,5,7,11,13,17,19}
class Solution:
def countPrimeSetBits(self, left: int, right: int) -> int:
return sum(i.bit_count() in PRIMES for i in range(left, right + 1))