classSolution{public:
string shortestPalindrome(string s){
string t(s.rbegin(), s.rend());int n = s.size();
s =' '+ s +'#'+ t;
vector<int>ne(n *2+2);for(int i =2, j =0; i <= n *2+1; i ++){while(j && s[i]!= s[j +1]) j = ne[j];if(s[i]== s[j +1]) j ++;
ne[i]= j;}int len = ne[n *2+1];
string left = s.substr(1, len), right = s.substr(1+ len, n - len);returnstring(right.rbegin(), right.rend())+ left + right;}};
classSolution{public String shortestPalindrome(String s){int n = s.length();int base =131, mod =1000000007;int left =0, right =0, mul =1;int best =-1;for(int i =0; i < n;++i){
left =(int)(((long) left * base + s.charAt(i))% mod);
right =(int)((right +(long) mul * s.charAt(i))% mod);if(left == right){
best = i;}
mul =(int)((long) mul * base % mod);}
String add =(best == n -1?"": s.substring(best +1));
StringBuffer ans =newStringBuffer(add).reverse();
ans.append(s);return ans.toString();}}
classSolution:defshortestPalindrome(self, s:str)->str:
n =len(s)
base, mod =131,10**9+7
left = right =0
mul =1
best =-1for i inrange(n):
left =(left * base +ord(s[i]))% mod
right =(right + mul *ord(s[i]))% mod
if left == right:
best = i
mul = mul * base % mod
add =(""if best == n -1else s[best+1:])return add[::-1]+ s
funcshortestPalindrome(s string)string{
n :=len(s)
base, mod :=131,1000000007
left, right, mul :=0,0,1
best :=-1for i :=0; i < n; i++{
left =(left * base +int(s[i]-'0'))% mod
right =(right + mul *int(s[i]-'0'))% mod
if left == right {
best = i
}
mul = mul * base % mod
}
add :=""if best != n -1{
add = s[best +1:]}
b :=[]byte(add)for i :=0; i <len(b)/2; i++{
b[i], b[len(b)-1-i]= b[len(b)-1-i], b[i]}returnstring(b)+ s
}
第二百一十五题:
classSolution{public:intquick_sort(vector<int>& nums,int l,int r,int k){if(l == r)return nums[k];int x = nums[l], i = l -1, j = r +1;while(i < j){do i ++;while(nums[i]> x);do j --;while(nums[j]< x);if(i < j)swap(nums[i], nums[j]);}if(k <= j)returnquick_sort(nums, l, j, k);elsereturnquick_sort(nums, j +1, r, k);}intfindKthLargest(vector<int>& nums,int k){returnquick_sort(nums,0, nums.size()-1, k -1);}};
classSolution{
Random random =newRandom();publicintfindKthLargest(int[] nums,int k){returnquickSelect(nums,0, nums.length -1, nums.length - k);}publicintquickSelect(int[] a,int l,int r,int index){int q =randomPartition(a, l, r);if(q == index){return a[q];}else{return q < index ?quickSelect(a, q +1, r, index):quickSelect(a, l, q -1, index);}}publicintrandomPartition(int[] a,int l,int r){int i = random.nextInt(r - l +1)+ l;swap(a, i, r);returnpartition(a, l, r);}publicintpartition(int[] a,int l,int r){int x = a[r], i = l -1;for(int j = l; j < r;++j){if(a[j]<= x){swap(a,++i, j);}}swap(a, i +1, r);return i +1;}publicvoidswap(int[] a,int i,int j){int temp = a[i];
a[i]= a[j];
a[j]= temp;}}
classSolution:deffindKthLargest(self, nums: List[int], k:int)->int:
nums =[-1*num for num in nums]
heapq.heapify(nums)for i inrange(k-1):
heapq.heappop(nums)return-1*heapq.heappop(nums)
funcfindKthLargest(nums []int, k int)int{
rand.Seed(time.Now().UnixNano())returnquickSelect(nums,0,len(nums)-1,len(nums)-k)}funcquickSelect(a []int, l, r, index int)int{
q :=randomPartition(a, l, r)if q == index {return a[q]}elseif q < index {returnquickSelect(a, q +1, r, index)}returnquickSelect(a, l, q -1, index)}funcrandomPartition(a []int, l, r int)int{
i := rand.Int()%(r - l +1)+ l
a[i], a[r]= a[r], a[i]returnpartition(a, l, r)}funcpartition(a []int, l, r int)int{
x := a[r]
i := l -1for j := l; j < r; j++{if a[j]<= x {
i++
a[i], a[j]= a[j], a[i]}}
a[i+1], a[r]= a[r], a[i+1]return i +1}
第二百一十六题:
classSolution{public:
vector<vector<int>> ans;
vector<int> path;
vector<vector<int>>combinationSum3(int k,int n){dfs(1, n, k);return ans;}voiddfs(int start,int n,int k){if(!n){if(!k) ans.push_back(path);}elseif(k){for(int i = start; i <=9; i ++)if(n >= i){
path.push_back(i);dfs(i +1, n - i, k -1);
path.pop_back();}}}};
classSolution{
List<Integer> temp =newArrayList<Integer>();
List<List<Integer>> ans =newArrayList<List<Integer>>();public List<List<Integer>>combinationSum3(int k,int n){dfs(1,9, k, n);return ans;}publicvoiddfs(int cur,int n,int k,int sum){if(temp.size()+(n - cur +1)< k || temp.size()> k){return;}if(temp.size()== k){int tempSum =0;for(int num : temp){
tempSum += num;}if(tempSum == sum){
ans.add(newArrayList<Integer>(temp));return;}}
temp.add(cur);dfs(cur +1, n, k, sum);
temp.remove(temp.size()-1);dfs(cur +1, n, k, sum);}}
classSolution(object):defcombinationSum3(self, k, n):"""
:type k: int
:type n: int
:rtype: List[List[int]]
"""defdfs(path,begin):# path:保存所经过的路径# begin:每层回溯开始的节点,使下一层回溯可以从自身位置+1的地方开始,排除重复使用之前元素的可能ifsum(path)== n andlen(path)==k:##如果遍历的和等于n且长度也等于k,符合条件则加入res
res.append(path[:])returnifsum(path)> n orlen(path)==k:#路径元素总和大于n或者长度等于n却没有加入res,说明不符合条件,剪枝returnfor i inrange(begin,10):
dfs(path+[i],i+1)
res =[]#结果数组
path =[]#保存每一次的路径
begin =1#回溯起始的位置,题目说的是1-9,所以设置为1
dfs(path,begin)return res
funccombinationSum3(k int, n int)(ans [][]int){var temp []intvar dfs func(cur, rest int)
dfs =func(cur, rest int){// 找到一个答案iflen(temp)== k && rest ==0{
ans =append(ans,append([]int(nil), temp...))return}// 剪枝:跳过的数字过多,后面已经无法选到 k 个数字iflen(temp)+10-cur < k || rest <0{return}// 跳过当前数字dfs(cur+1, rest)// 选当前数字
temp =append(temp, cur)dfs(cur+1, rest-cur)
temp = temp[:len(temp)-1]}dfs(1, n)return}
classSolution{publicbooleancontainsDuplicate(int[] nums){
Set<Integer> set =newHashSet<Integer>();for(int x : nums){if(!set.add(x)){returntrue;}}returnfalse;}}
funccontainsDuplicate(nums []int)bool{
set :=map[int]struct{}{}for_, v :=range nums {if_, has := set[v]; has {returntrue}
set[v]=struct{}{}}returnfalse}
classSolution{/**
* Divide-and-conquer algorithm to solve skyline problem,
* which is similar with the merge sort algorithm.
*/public List<List<Integer>>getSkyline(int[][] buildings){int n = buildings.length;
List<List<Integer>> output =newArrayList<List<Integer>>();// The base cases if(n ==0)return output;if(n ==1){int xStart = buildings[0][0];int xEnd = buildings[0][1];int y = buildings[0][2];
output.add(newArrayList<Integer>(){{add(xStart);add(y);}});
output.add(newArrayList<Integer>(){{add(xEnd);add(0);}});// output.add(new int[]{xStart, y});// output.add(new int[]{xEnd, 0});return output;}// If there is more than one building, // recursively divide the input into two subproblems.
List<List<Integer>> leftSkyline, rightSkyline;
leftSkyline =getSkyline(Arrays.copyOfRange(buildings,0, n /2));
rightSkyline =getSkyline(Arrays.copyOfRange(buildings, n /2, n));// Merge the results of subproblem together.returnmergeSkylines(leftSkyline, rightSkyline);}/**
* Merge two skylines together.
*/public List<List<Integer>>mergeSkylines(List<List<Integer>> left, List<List<Integer>> right){int nL = left.size(), nR = right.size();int pL =0, pR =0;int currY =0, leftY =0, rightY =0;int x, maxY;
List<List<Integer>> output =newArrayList<List<Integer>>();// while we're in the region where both skylines are presentwhile((pL < nL)&&(pR < nR)){
List<Integer> pointL = left.get(pL);
List<Integer> pointR = right.get(pR);// pick up the smallest xif(pointL.get(0)< pointR.get(0)){
x = pointL.get(0);
leftY = pointL.get(1);
pL++;}else{
x = pointR.get(0);
rightY = pointR.get(1);
pR++;}// max height (i.e. y) between both skylines
maxY = Math.max(leftY, rightY);// update output if there is a skyline changeif(currY != maxY){updateOutput(output, x, maxY);
currY = maxY;}}// there is only left skylineappendSkyline(output, left, pL, nL, currY);// there is only right skylineappendSkyline(output, right, pR, nR, currY);return output;}/**
* Update the final output with the new element.
*/publicvoidupdateOutput(List<List<Integer>> output,int x,int y){// if skyline change is not vertical - // add the new pointif(output.isEmpty()|| output.get(output.size()-1).get(0)!= x)
output.add(newArrayList<Integer>(){{add(x);add(y);}});// if skyline change is vertical - // update the last pointelse{
output.get(output.size()-1).set(1, y);}}/**
* Append the rest of the skyline elements with indice (p, n)
* to the final output.
*/publicvoidappendSkyline(List<List<Integer>> output, List<List<Integer>> skyline,int p,int n,int currY){while(p < n){
List<Integer> point = skyline.get(p);int x = point.get(0);int y = point.get(1);
p++;// update output// if there is a skyline changeif(currY != y){updateOutput(output, x, y);
currY = y;}}}}
classSolution:defgetSkyline(self, buildings:'List[List[int]]')->'List[List[int]]':"""
Divide-and-conquer algorithm to solve skyline problem,
which is similar with the merge sort algorithm.
"""
n =len(buildings)# The base casesif n ==0:return[]if n ==1:
x_start, x_end, y = buildings[0]return[[x_start, y],[x_end,0]]# If there is more than one building, # recursively divide the input into two subproblems.
left_skyline = self.getSkyline(buildings[: n //2])
right_skyline = self.getSkyline(buildings[n //2:])# Merge the results of subproblem together.return self.merge_skylines(left_skyline, right_skyline)defmerge_skylines(self, left, right):"""
Merge two skylines together.
"""defupdate_output(x, y):"""
Update the final output with the new element.
"""# if skyline change is not vertical - # add the new pointifnot output or output[-1][0]!= x:
output.append([x, y])# if skyline change is vertical - # update the last pointelse:
output[-1][1]= y
defappend_skyline(p, lst, n, y, curr_y):"""
Append the rest of the skyline elements with indice (p, n)
to the final output.
"""while p < n:
x, y = lst[p]
p +=1if curr_y != y:
update_output(x, y)
curr_y = y
n_l, n_r =len(left),len(right)
p_l = p_r =0
curr_y = left_y = right_y =0
output =[]# while we're in the region where both skylines are presentwhile p_l < n_l and p_r < n_r:
point_l, point_r = left[p_l], right[p_r]# pick up the smallest xif point_l[0]< point_r[0]:
x, left_y = point_l
p_l +=1else:
x, right_y = point_r
p_r +=1# max height (i.e. y) between both skylines
max_y =max(left_y, right_y)# if there is a skyline changeif curr_y != max_y:
update_output(x, max_y)
curr_y = max_y
# there is only left skyline
append_skyline(p_l, left, n_l, left_y, curr_y)# there is only right skyline
append_skyline(p_r, right, n_r, right_y, curr_y)return output
funcgetSkyline(buildings [][]int)[][]int{type boxing struct{
node, pos, height, side int}// 标记并排序输入形状所有的拐点,每个矩形两个点。var box []boxing
for i, v :=range buildings {
box =append(box, boxing{i, v[0], v[2],0}, boxing{i, v[1], v[2],1})}
sort.Slice(box,func(i, j int)bool{return box[i].pos < box[j].pos
})var hill, result [][]int
maxhill :=-1for i :=0; i <len(box); i++{
v := box[i]if v.side ==0{// push 拐点
hill =append(hill,[]int{v.height, v.node})}else{// pop 拐点for id, vv :=range hill {if vv[1]== v.node {
hill =append(hill[:id], hill[id+1:]...)break}}}// 当前位置(x),最高点(y)查找。
maxh :=0for_, vv :=range hill {if vv[0]> maxh {
maxh = vv[0]}}if!(i <len(box)-1&& box[i].pos == box[i+1].pos){// 同一个位置(x)的出现多个(Y)的处理// 当前最高点和历史最高点(前序)存在变化Delta则必须记录之(Result)if maxhill < maxh || maxhill > maxh {
result =append(result,[]int{v.pos, maxh})}
maxhill = maxh
}}return result
}
第二百一十九题:
classSolution{public:boolcontainsNearbyDuplicate(vector<int>& nums,int k){
unordered_map<int,int> hash;for(int i =0; i < nums.size(); i ++){int x = nums[i];if(hash.count(x)&& i - hash[x]<= k)returntrue;
hash[x]= i;}returnfalse;}};
publicbooleancontainsNearbyDuplicate(int[] nums,int k){
Set<Integer> set =newHashSet<>();for(int i =0; i < nums.length;++i){if(set.contains(nums[i]))returntrue;
set.add(nums[i]);if(set.size()> k){
set.remove(nums[i - k]);}}returnfalse;}
funccontainsNearbyDuplicate(nums []int, k int)bool{
m :=make(map[int]int,0)for i:=0;i<len(nums);i++{if_,ok := m[nums[i]];ok {if i - m[nums[i]]<= k {returntrue}}
m[nums[i]]=i
}returnfalse}
第二百二十题:
classSolution{public:boolcontainsNearbyAlmostDuplicate(vector<int>& nums,int k,int t){typedeflonglong LL;
multiset<LL> S;
S.insert(1e18), S.insert(-1e18);for(int i =0, j =0; i < nums.size(); i ++){if(i - j > k) S.erase(S.find(nums[j ++]));int x = nums[i];auto it = S.lower_bound(x);if(*it - x <= t)returntrue;-- it;if(x -*it <= t)returntrue;
S.insert(x);}returnfalse;}};
publicclassSolution{// Get the ID of the bucket from element value x and bucket width w// In Java, `-3 / 5 = 0` and but we need `-3 / 5 = -1`.privatelonggetID(long x,long w){return x <0?(x +1)/ w -1: x / w;}publicbooleancontainsNearbyAlmostDuplicate(int[] nums,int k,int t){if(t <0)returnfalse;
Map<Long, Long> d =newHashMap<>();long w =(long)t +1;for(int i =0; i < nums.length;++i){long m =getID(nums[i], w);// check if bucket m is empty, each bucket may contain at most one elementif(d.containsKey(m))returntrue;// check the nei***or buckets for almost duplicateif(d.containsKey(m -1)&& Math.abs(nums[i]- d.get(m -1))< w)returntrue;if(d.containsKey(m +1)&& Math.abs(nums[i]- d.get(m +1))< w)returntrue;// now bucket m is empty and no almost duplicate in nei***or buckets
d.put(m,(long)nums[i]);if(i >= k) d.remove(getID(nums[i - k], w));}returnfalse;}}
funccontainsNearbyAlmostDuplicate(nums []int, k int, t int)bool{
N :=len(nums)if N ==0{returnfalse}// discretize and delete duplicated values
ordered, hash, n :=discretize(nums)// Binary Indexed Trees: [1,n]
NN := n+1
tr :=make([]int, NN)
add :=func(i, v int){for; i < NN; i += i&-i {
tr[i]+= v
}}
sum :=func(i int)(sum int){for; i >0; i -= i&-i {
sum += tr[i]}return sum
}for i, v :=range nums {add(hash[v],1)if i >= k+1{add(hash[nums[i-k-1]],-1)}
l := sort.SearchInts(ordered, v-t)
r := sort.SearchInts(ordered, v+t)if r < n && ordered[r]== v+t {
r++}ifsum(r)-sum(l)>1{returntrue}}returnfalse}funcdiscretize(nums []int)([]int,map[int]int,int){
N :=len(nums)
hash :=make(map[int]int)// de-dupfor i :=0; i < N; i++{
hash[nums[i]]= i
}
ordered, n :=make([]int,len(hash)),0for k,_:=range hash {
ordered[n]= k
n++}
sort.Ints(ordered)for i :=0; i < n; i++{// BIT starts with index 1
hash[ordered[i]]= i+1}return ordered, hash, n
}