Welcome to Subscribe On Youtube

1505. Minimum Possible Integer After at Most K Adjacent Swaps On Digits

Description

You are 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.

 

Example 1:

Input: num = "4321", k = 4
Output: "1342"
Explanation: The steps to obtain the minimum integer from 4321 with 4 adjacent swaps are shown.

Example 2:

Input: num = "100", k = 1
Output: "010"
Explanation: It's ok for the output to have leading zeros, but the input is guaranteed not to have any leading zeros.

Example 3:

Input: num = "36789", k = 1000
Output: "36789"
Explanation: We can keep the number without any swaps.

 

Constraints:

  • 1 <= num.length <= 3 * 104
  • num consists of only digits and does not contain leading zeros.
  • 1 <= k <= 109

Solutions

Segment Tree.

  • class Solution {
        public String minInteger(String num, int k) {
            Queue<Integer>[] pos = new Queue[10];
            for (int i = 0; i < 10; ++i) {
                pos[i] = new ArrayDeque<>();
            }
            int n = num.length();
            for (int i = 0; i < n; ++i) {
                pos[num.charAt(i) - '0'].offer(i + 1);
            }
            StringBuilder ans = new StringBuilder();
            BinaryIndexedTree tree = new BinaryIndexedTree(n);
            for (int i = 1; i <= n; ++i) {
                for (int v = 0; v < 10; ++v) {
                    if (!pos[v].isEmpty()) {
                        Queue<Integer> q = pos[v];
                        int j = q.peek();
                        int dist = tree.query(n) - tree.query(j) + j - i;
                        if (dist <= k) {
                            k -= dist;
                            q.poll();
                            ans.append(v);
                            tree.update(j, 1);
                            break;
                        }
                    }
                }
            }
            return ans.toString();
        }
    }
    
    class BinaryIndexedTree {
        private int n;
        private int[] c;
    
        public BinaryIndexedTree(int n) {
            this.n = n;
            c = new int[n + 1];
        }
    
        public void update(int x, int delta) {
            while (x <= n) {
                c[x] += delta;
                x += lowbit(x);
            }
        }
    
        public int query(int x) {
            int s = 0;
            while (x > 0) {
                s += c[x];
                x -= lowbit(x);
            }
            return s;
        }
    
        public static int lowbit(int x) {
            return x & -x;
        }
    }
    
  • class BinaryIndexedTree {
    public:
        int n;
        vector<int> c;
    
        BinaryIndexedTree(int _n)
            : n(_n)
            , c(_n + 1) {}
    
        void update(int x, int delta) {
            while (x <= n) {
                c[x] += delta;
                x += lowbit(x);
            }
        }
    
        int query(int x) {
            int s = 0;
            while (x > 0) {
                s += c[x];
                x -= lowbit(x);
            }
            return s;
        }
    
        int lowbit(int x) {
            return x & -x;
        }
    };
    
    class Solution {
    public:
        string minInteger(string num, int k) {
            vector<queue<int>> pos(10);
            int n = num.size();
            for (int i = 0; i < n; ++i) pos[num[i] - '0'].push(i + 1);
            BinaryIndexedTree* tree = new BinaryIndexedTree(n);
            string ans = "";
            for (int i = 1; i <= n; ++i) {
                for (int v = 0; v < 10; ++v) {
                    auto& q = pos[v];
                    if (!q.empty()) {
                        int j = q.front();
                        int dist = tree->query(n) - tree->query(j) + j - i;
                        if (dist <= k) {
                            k -= dist;
                            q.pop();
                            ans += (v + '0');
                            tree->update(j, 1);
                            break;
                        }
                    }
                }
            }
            return ans;
        }
    };
    
  • class BinaryIndexedTree:
        def __init__(self, n):
            self.n = n
            self.c = [0] * (n + 1)
    
        @staticmethod
        def lowbit(x):
            return x & -x
    
        def update(self, x, delta):
            while x <= self.n:
                self.c[x] += delta
                x += BinaryIndexedTree.lowbit(x)
    
        def query(self, x):
            s = 0
            while x:
                s += self.c[x]
                x -= BinaryIndexedTree.lowbit(x)
            return s
    
    
    class Solution:
        def minInteger(self, num: str, k: int) -> str:
            pos = defaultdict(deque)
            for i, v in enumerate(num, 1):
                pos[int(v)].append(i)
            ans = []
            n = len(num)
            tree = BinaryIndexedTree(n)
            for i in range(1, n + 1):
                for v in range(10):
                    q = pos[v]
                    if q:
                        j = q[0]
                        dist = tree.query(n) - tree.query(j) + j - i
                        if dist <= k:
                            k -= dist
                            q.popleft()
                            ans.append(str(v))
                            tree.update(j, 1)
                            break
            return ''.join(ans)
    
    
  • type BinaryIndexedTree struct {
    	n int
    	c []int
    }
    
    func newBinaryIndexedTree(n int) *BinaryIndexedTree {
    	c := make([]int, n+1)
    	return &BinaryIndexedTree{n, c}
    }
    
    func (this *BinaryIndexedTree) lowbit(x int) int {
    	return x & -x
    }
    
    func (this *BinaryIndexedTree) update(x, delta int) {
    	for x <= this.n {
    		this.c[x] += delta
    		x += this.lowbit(x)
    	}
    }
    
    func (this *BinaryIndexedTree) query(x int) int {
    	s := 0
    	for x > 0 {
    		s += this.c[x]
    		x -= this.lowbit(x)
    	}
    	return s
    }
    
    func minInteger(num string, k int) string {
    	pos := make([][]int, 10)
    	for i, c := range num {
    		pos[c-'0'] = append(pos[c-'0'], i+1)
    	}
    	n := len(num)
    	tree := newBinaryIndexedTree(n)
    	var ans strings.Builder
    	for i := 1; i <= n; i++ {
    		for v := 0; v < 10; v++ {
    			if len(pos[v]) > 0 {
    				j := pos[v][0]
    				dist := tree.query(n) - tree.query(j) + j - i
    				if dist <= k {
    					k -= dist
    					pos[v] = pos[v][1:]
    					ans.WriteByte(byte(v + '0'))
    					tree.update(j, 1)
    					break
    				}
    			}
    		}
    	}
    	return ans.String()
    }
    

All Problems

All Solutions