link
Given a string num representing the digits of a very large integer and an integer k.
You are allowed to swap any two adjacent digits of the integer at most k times.
Return the minimum integer you can obtain also as a string.
- BIT
class Solution {
public:
int fenwick[30001];
int n;
priority_queue<int,vector<int>,greater<int>> pq[10];
string minInteger(string num, int k) {
n=num.size();
for(int i=0;i<num.size();i++){
pq[num[i]-'0'].push(i);
}
int idx=0;
string res="";
while(idx<n){
for(int i=0;i<=9;i++){
if(pq[i].empty()) continue;
int mi=pq[i].top();
int t=mi-query(mi-1);
if(t<=k){
res+=to_string(i);
pq[i].pop();
k-=t;
update(mi);
break;
}
}
idx++;
}
return res;
}
void update(int idx){
idx++;
while(idx<=n){
fenwick[idx]+=1;
idx+=(idx&(-idx));
}
}
int query(int idx){
idx++;
int res=0;
while(idx>0){
res+=fenwick[idx];
idx-=(idx&(-idx));
}
return res;
}
};
- segment tree
class Solution {
public:
int seg[30001<<2];
int n;
priority_queue<int,vector<int>,greater<int>> pq[10];
string minInteger(string num, int k) {
n=num.size();
for(int i=0;i<num.size();i++){
pq[num[i]-'0'].push(i);
}
int idx=0;
string res="";
while(idx<n){
for(int i=0;i<=9;i++){
if(pq[i].empty()) continue;
int mi=pq[i].top();
int t=mi-query(0,mi-1,0,0,n-1);
if(t<=k){
res+=to_string(i);
pq[i].pop();
k-=t;
update(mi,0,0,n-1);
break;
}
}
idx++;
}
return res;
}
int query(int qleft, int qright, int idx, int left, int right){
if(qleft>right || qright<left) return 0;
if(qleft<=left && qright>=right) return seg[idx];
int mid=(left+right)/2;
return query(qleft,qright,idx*2+1,left,mid) + query(qleft,qright,idx*2+2,mid+1,right);
}
void update(int ui, int idx, int left, int right){
if(ui<left || ui>right) return;
if(left==right){
seg[idx]++;
return;
}
int mid=(left+right)/2;
update(ui,idx*2+1,left,mid);
update(ui,idx*2+2,mid+1,right);
seg[idx]=seg[idx*2+1]+seg[idx*2+2];
}
};