classSolution{public:intlargestPalindrome(int n){typedeflonglong LL;if(n ==1)return9;int maxv =pow(10, n)-1;for(int i = maxv;;i --){auto a =to_string(i);auto b = a;reverse(b.begin(), b.end());auto num =stoll(a + b);for(LL j = maxv; j * j >= num; j --)if(num % j ==0)return num %1337;}return0;}};
classSolution{publicintlargestPalindrome(int n){if(n ==1)return9;//计算给定位数的最大值long max =(long)Math.pow(10,n)-1;//从max - 1开始循环,原因见上文for(long i = max -1; i > max /10; i--){//1. 构造回文数
String s1 = String.valueOf(i);long rev = Long.parseLong(s1 +newStringBuilder(s1).reverse().toString());//2. 检验该回文数能否由给定的数相乘得到for(long x = max; x * x >= rev; x --){if(rev % x ==0)return(int)(rev %1337);}}return-1;}}
classSolution:deflargestPalindrome(self, n:int)->int:if n ==1:return9
a =2
hi =10** n -1
lo =10**(n -1)while a <2*10** n:
upper =10** n - a
lower =int(str(upper)[::-1])if a **2-4* lower >=0and(a **2-4* lower)**0.5==int((a **2-4* lower)**0.5):
num =int(str(upper)+str(upper)[::-1])return num %1337
a +=1
varlargestPalindrome=function(n){if(n ===1)return9;if(n ===8)return475;for(let end =+(newArray(n).fill(9).join('')), i = end -1; i >=1;--i){let num =+(i + i.toString().split('').reverse().join(''))for(let temp = end, start = Math.ceil(Math.sqrt(num)); temp >= start;--temp){if(num % temp ===0){return num %1337}}}};
第四百八十题:
classSolution{public:int k;
multiset<int> left, right;doubleget_medium(){if(k %2)return*right.begin();return((double)*left.rbegin()+*right.begin())/2;}
vector<double>medianSlidingWindow(vector<int>& nums,int _k){
k = _k;for(int i =0; i < k; i ++) right.insert(nums[i]);for(int i =0; i < k /2; i ++){
left.insert(*right.begin());
right.erase(right.begin());}
vector<double> res;
res.push_back(get_medium());for(int i = k; i < nums.size(); i ++){int x = nums[i], y = nums[i - k];if(x >=*right.begin()) right.insert(x);else left.insert(x);if(y >=*right.begin()) right.erase(right.find(y));else left.erase(left.find(y));while(left.size()> right.size()){
right.insert(*left.rbegin());
left.erase(left.find(*left.rbegin()));}while(right.size()> left.size()+1){
left.insert(*right.begin());
right.erase(right.begin());}
res.push_back(get_medium());}return res;}};
classSolution{publicdouble[]medianSlidingWindow(int[] nums,int k){
DualHeap dh =newDualHeap(k);for(int i =0; i < k;++i){
dh.insert(nums[i]);}double[] ans =newdouble[nums.length - k +1];
ans[0]= dh.getMedian();for(int i = k; i < nums.length;++i){
dh.insert(nums[i]);
dh.erase(nums[i - k]);
ans[i - k +1]= dh.getMedian();}return ans;}}classDualHeap{// 大根堆,维护较小的一半元素private PriorityQueue<Integer> small;// 小根堆,维护较大的一半元素private PriorityQueue<Integer> large;// 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数private Map<Integer, Integer> delayed;privateint k;// small 和 large 当前包含的元素个数,需要扣除被「延迟删除」的元素privateint smallSize, largeSize;publicDualHeap(int k){this.small =newPriorityQueue<Integer>(newComparator<Integer>(){publicintcompare(Integer num1, Integer num2){return num2.compareTo(num1);}});this.large =newPriorityQueue<Integer>(newComparator<Integer>(){publicintcompare(Integer num1, Integer num2){return num1.compareTo(num2);}});this.delayed =newHashMap<Integer, Integer>();this.k = k;this.smallSize =0;this.largeSize =0;}publicdoublegetMedian(){return(k &1)==1? small.peek():((double) small.peek()+ large.peek())/2;}publicvoidinsert(int num){if(small.isEmpty()|| num <= small.peek()){
small.offer(num);++smallSize;}else{
large.offer(num);++largeSize;}makeBalance();}publicvoiderase(int num){
delayed.put(num, delayed.getOrDefault(num,0)+1);if(num <= small.peek()){--smallSize;if(num == small.peek()){prune(small);}}else{--largeSize;if(num == large.peek()){prune(large);}}makeBalance();}// 不断地弹出 heap 的堆顶元素,并且更新哈希表privatevoidprune(PriorityQueue<Integer> heap){while(!heap.isEmpty()){int num = heap.peek();if(delayed.containsKey(num)){
delayed.put(num, delayed.get(num)-1);if(delayed.get(num)==0){
delayed.remove(num);}
heap.poll();}else{break;}}}// 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求privatevoidmakeBalance(){if(smallSize > largeSize +1){// small 比 large 元素多 2 个
large.offer(small.poll());--smallSize;++largeSize;// small 堆顶元素被移除,需要进行 pruneprune(small);}elseif(smallSize < largeSize){// large 比 small 元素多 1 个
small.offer(large.poll());++smallSize;--largeSize;// large 堆顶元素被移除,需要进行 pruneprune(large);}}}
classDualHeap:def__init__(self, k:int):# 大根堆,维护较小的一半元素,注意 python 没有大根堆,需要将所有元素取相反数并使用小根堆
self.small =list()# 小根堆,维护较大的一半元素
self.large =list()# 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数
self.delayed = collections.Counter()
self.k = k
# small 和 large 当前包含的元素个数,需要扣除被「延迟删除」的元素
self.smallSize =0
self.largeSize =0# 不断地弹出 heap 的堆顶元素,并且更新哈希表defprune(self, heap: List[int]):while heap:
num = heap[0]if heap is self.small:
num =-num
if num in self.delayed:
self.delayed[num]-=1if self.delayed[num]==0:
self.delayed.pop(num)
heapq.heappop(heap)else:break# 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求defmakeBalance(self):if self.smallSize > self.largeSize +1:# small 比 large 元素多 2 个
heapq.heappush(self.large,-self.small[0])
heapq.heappop(self.small)
self.smallSize -=1
self.largeSize +=1# small 堆顶元素被移除,需要进行 prune
self.prune(self.small)elif self.smallSize < self.largeSize:# large 比 small 元素多 1 个
heapq.heappush(self.small,-self.large[0])
heapq.heappop(self.large)
self.smallSize +=1
self.largeSize -=1# large 堆顶元素被移除,需要进行 prune
self.prune(self.large)definsert(self, num:int):ifnot self.small or num <=-self.small[0]:
heapq.heappush(self.small,-num)
self.smallSize +=1else:
heapq.heappush(self.large, num)
self.largeSize +=1
self.makeBalance()deferase(self, num:int):
self.delayed[num]+=1if num <=-self.small[0]:
self.smallSize -=1if num ==-self.small[0]:
self.prune(self.small)else:
self.largeSize -=1if num == self.large[0]:
self.prune(self.large)
self.makeBalance()defgetMedian(self)->float:returnfloat(-self.small[0])if self.k %2==1else(-self.small[0]+ self.large[0])/2classSolution:defmedianSlidingWindow(self, nums: List[int], k:int)-> List[float]:
dh = DualHeap(k)for num in nums[:k]:
dh.insert(num)
ans =[dh.getMedian()]for i inrange(k,len(nums)):
dh.insert(nums[i])
dh.erase(nums[i - k])
ans.append(dh.getMedian())return ans
type hp struct{
sort.IntSlice
size int}func(h *hp)Push(v interface{}){ h.IntSlice =append(h.IntSlice, v.(int))}func(h *hp)Pop()interface{}{ a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1];return v }func(h *hp)push(v int){ h.size++; heap.Push(h, v)}func(h *hp)pop()int{ h.size--;return heap.Pop(h).(int)}func(h *hp)prune(){for h.Len()>0{
num := h.IntSlice[0]if h == small {
num =-num
}if d, has := delayed[num]; has {if d >1{
delayed[num]--}else{delete(delayed, num)}
heap.Pop(h)}else{break}}}var delayed map[int]intvar small, large *hp
funcmedianSlidingWindow(nums []int, k int)[]float64{
delayed =map[int]int{}// 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数
small =&hp{}// 大根堆,维护较小的一半元素
large =&hp{}// 小根堆,维护较大的一半元素
makeBalance :=func(){// 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求if small.size > large.size+1{// small 比 large 元素多 2 个
large.push(-small.pop())
small.prune()// small 堆顶元素被移除,需要进行 prune}elseif small.size < large.size {// large 比 small 元素多 1 个
small.push(-large.pop())
large.prune()// large 堆顶元素被移除,需要进行 prune}}
insert :=func(num int){if small.Len()==0|| num <=-small.IntSlice[0]{
small.push(-num)}else{
large.push(num)}makeBalance()}
erase :=func(num int){
delayed[num]++if num <=-small.IntSlice[0]{
small.size--if num ==-small.IntSlice[0]{
small.prune()}}else{
large.size--if num == large.IntSlice[0]{
large.prune()}}makeBalance()}
getMedian :=func()float64{if k&1>0{returnfloat64(-small.IntSlice[0])}returnfloat64(-small.IntSlice[0]+large.IntSlice[0])/2}for_, num :=range nums[:k]{insert(num)}
n :=len(nums)
ans :=make([]float64,1, n-k+1)
ans[0]=getMedian()for i := k; i < n; i++{insert(nums[i])erase(nums[i-k])
ans =append(ans,getMedian())}return ans
}
第四百八十一题:
classSolution{public:intmagicalString(int n){
string s ="122";for(int i =2, k =1; s.size()< n; i ++, k =3- k){for(int j =0; j < s[i]-'0'; j ++)
s +=to_string(k);}int res =0;for(int i =0; i < n; i ++) res += s[i]=='1';return res;}};
classSolution{publicintmagicalString(int n){if(n <=0)return0;if(n ==1)return1;
StringBuilder sb =newStringBuilder();
sb.append(1);int cnt =1, i =1, low =0;char cur ='1';while(i < n){//填的数量就由走的慢的指针决定char former = sb.charAt(low++);//每次把一种数字填充完,如果上次填的1,那么这次就是2
cur = cur =='1'?'2':'1';if(former =='1'){if(cur =='1') cnt++;
sb.append(cur);
i++;}else{if(cur =='1') cnt +=2;
sb.append(cur);
sb.append(cur);
i +=2;}}//判断最后是否计入了 n 之后的 1,如有就去掉if(i == n && cur =='1') cnt--;if(i == n +1&& cur =='1') cnt -=2;return cnt;}}
classSolution:defmagicalString(self, n:int)->int:
a1 =[1,2]+[0]*(n -2)
a2 =[1,2,2]
i =2whilelen(a2)< n:
a1[i]= a2[i]
a2.extend([3- a2[-1]]* a1[i])
i +=1return collections.Counter(a2[:n])[1]
funcmagicalString(n int)int{if n ==0{return0}
s :=make([]byte,0, n+2)
s =append(s,'1','2','2')
next :=2
res :=1for i :=2; i < n; i++{if s[i]=='1'{
res++if s[next]=='2'{
s =append(s,'1')}else{
s =append(s,'2')}}else{if s[next]=='2'{
s =append(s,'1','1')}else{
s =append(s,'2','2')}
next++}
next++}return res
}
第四百八十二题:
classSolution{public:
string licenseKeyFormatting(string S,int K){
string s;for(auto c: S)if(c !='-')
s += c;
string res;for(int i =0; i < s.size()% K; i ++) res +=toupper(s[i]);for(int i = s.size()% K; i < s.size();){if(res.size()) res +='-';for(int j =0; j < K; j ++)
res +=toupper(s[i ++]);}return res;}};
classSolution{public String licenseKeyFormatting(String S,int K){
StringBuilder s =newStringBuilder();// 统计已打印字符个数int count =0;// 倒序遍历字符串for(int i = S.length()-1; i >=0; i--){if(S.charAt(i)!='-'){// 计算什么时候打印分隔符if(count !=0&& count % K ==0){
s.append('-');}// 转为大写字母添加
s.append(Character.toUpperCase(S.charAt(i)));
count++;}}// 反转字符串return s.reverse().toString();}}
classSolution:deflicenseKeyFormatting(self, S:str, K:int)->str:
st = S.replace('-','').upper()
a =len(st)if a ==0:return''
b = a%K
if b ==0:
c =(a//K)-1
b = K
else:
c = a//K
s = st[:b]while c !=0:
s +='-'+ st[b:b+K]
b = b+K
c -=1return s
funclicenseKeyFormatting(S string, K int)string{
str := strings.ReplaceAll(S,"-","")for i :=len(str)- K; i >0; i -= K {
str = str[:i]+"-"+ str[i:]}return strings.ToUpper(str)}
第四百八十三题:
classSolution{public:
string smallestGoodBase(string number){typedeflonglong LL;
LL n =stoll(number);for(int t =log2(n)+1; t >=3; t --){
LL k =pow(n,1.0/(t -1));
LL r =0;for(int i =0; i < t; i ++) r = r * k +1;if(r == n)returnto_string(k);}returnto_string(n -1);}};
public String smallestGoodBase(String n){long N = Long.parseLong(n);for(int m =59; m >1; m--){long k =(long) Math.pow(N,1.0/ m);//不存在1进制,如果k<=1,直接下一次if(k <=1)continue;long s =0;for(int i =0; i <= m; i++)
s = s * k +1;if(s == N)return String.valueOf(k);}return String.valueOf(N -1);}
classSolution:defsmallestGoodBase(self, n:str)->str:
n =int(n)# 上面提到的 base 进制转十进制公式。# 使用等比数列求和公式可简化时间复杂度defsum_with(base, N):return(1- base ** N)//(1- base)# return sum(1 * base ** i for i in range(N))# bin(n) 会计算出 n 的二进制表示, 其会返回形如 '0b10111' 的字符串,因此需要减去 2。for N inrange(len(bin(n))-2,0,-1):
l =2
r = n -1while l <= r:
mid =(l + r)//2
v = sum_with(mid, N)if v < n:
l = mid +1elif v > n:
r = mid -1else:returnstr(mid)
classSolution{public:intfindMaxConsecutiveOnes(vector<int>& nums){int res =0;for(int i =0; i < nums.size(); i ++){if(nums[i]==0)continue;int j = i +1;while(j < nums.size()&& nums[j]==1) j ++;
res =max(res, j - i);
i = j;}return res;}};
classSolution{publicintfindMaxConsecutiveOnes(int[] nums){int maxCount =0, count =0;int n = nums.length;for(int i =0; i < n; i++){if(nums[i]==1){
count++;}else{
maxCount = Math.max(maxCount, count);
count =0;}}
maxCount = Math.max(maxCount, count);return maxCount;}}
classSolution:deffindMaxConsecutiveOnes(self, nums: List[int])->int:
maxCount = count =0for i, num inenumerate(nums):if num ==1:
count +=1else:
maxCount =max(maxCount, count)
count =0
maxCount =max(maxCount, count)return maxCount
funcfindMaxConsecutiveOnes(nums []int)(maxCnt int){
cnt :=0for_, v :=range nums {if v ==1{
cnt++}else{
maxCnt =max(maxCnt, cnt)
cnt =0}}
maxCnt =max(maxCnt, cnt)return}funcmax(a, b int)int{if a > b {return a
}return b
}
第四百八十六题:
classSolution{public:boolPredictTheWinner(vector<int>& nums){int n = nums.size();
vector<vector<int>>f(n, vector<int>(n));for(int len =1; len <= n; len ++){for(int i =0; i + len -1< n; i ++){int j = i + len -1;if(len ==1) f[i][j]= nums[i];else{
f[i][j]=max(nums[i]- f[i +1][j], nums[j]- f[i][j -1]);}}}return f[0][n -1]>=0;}};
classSolution{publicbooleanPredictTheWinner(int[] nums){int length = nums.length;int[] dp =newint[length];for(int i =0; i < length; i++){
dp[i]= nums[i];}for(int i = length -2; i >=0; i--){for(int j = i +1; j < length; j++){
dp[j]= Math.max(nums[i]- dp[j], nums[j]- dp[j -1]);}}return dp[length -1]>=0;}}
classSolution:defPredictTheWinner(self, nums: List[int])->bool:
length =len(nums)
dp =[0]* length
for i, num inenumerate(nums):
dp[i]= num
for i inrange(length -2,-1,-1):for j inrange(i +1, length):
dp[j]=max(nums[i]- dp[j], nums[j]- dp[j -1])return dp[length -1]>=0
funcPredictTheWinner(nums []int)bool{
length :=len(nums)
dp :=make([]int, length)for i :=0; i < length; i++{
dp[i]= nums[i]}for i := length -2; i >=0; i--{for j := i +1; j < length; j++{
dp[j]=max(nums[i]- dp[j], nums[j]- dp[j -1])}}return dp[length -1]>=0}funcmax(x, y int)int{if x > y {return x
}return y
}