LC402. Move K digits

Move K digits


Problem description:
  Given a non-negative integer num represented by a string, remove the k-digit number in this number to make the remaining number the smallest.

note:

The length of num is less than 10002 and ≥ k.
num will not contain any leading zeros.

Example 1:

Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three numbers 4, 3, and 2 to form a new smallest number 1219.

Example 2:

Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the first 1 and the remaining number is 200. Note that the output cannot have any leading zeros.

Example 3:

Input: num = "10", k = 2
Output: "0"
Explanation: Remove all digits from the original digits, and leave the rest blank to be zero.


Problem Solving Idea 1:

1. Greedy strategy.

2. The question requires removal of k numbers. My method is to extract num.size ()-k numbers in the appropriate range, because you ca n’t do it with greed, you can remove the largest or smallest number each time. None of the answers are correct.

1432219 Remove the largest: 1221; remove the smallest: 4329 (more wrong).

3. What is the appropriate range? For example: num = "1432219", k = 3; it is to find 7-3, 4 numbers. The first time you have to look for it from 1432, the next three of 219 can't move, because you have found one, you have to make sure there are three, and you have enough four.

4. The key is how to deal with it after finding it. As shown below: 1432, after finding 1, save 1 and intercept the number after 1: 432219.

5. Search and intercept in the appropriate range, and finally you can get the correct answer, but the time complexity and space complexity are too high.

The code is as follows 1:

string removeKdigits(string num, int k) {
        if(num.size()<=k){//长度小于等于k则直接返回“0”
            return "0";
        }
        string s;
        k=num.size()-k;
        while(k--){//选取num.size()-k个
            char ch='9';
            int n=0;//位置,方便截取
            for(int i=0;i<num.size()-k;i++){//合适的范围
            if(num[i]<ch){//寻找最小
                ch=num[i];
                n=i;
            }
      	  }
      	    num=num.substr(n+1);//截取
            s+=ch;//加上
        }
        int i=0;
		while(s[i]=='0'){//开头的清零
			i++;
		}
		s=s.substr(i);
        if(s.size()==0){//清完0可能位空,所以这里要返回0
            return "0";
        }
        return s;
    }

Solution 2:

1. The above method, select the smallest in the appropriate range and then extract, you can use the stack to improve efficiency.

2. Cyclically judge each character of num and determine whether the element at the top of the stack is larger than the character. If it is, it will pop out of the stack, otherwise it will pop onto the stack, and there is a feeling of sorting the strings from small to large.

3. Note that the stack is deleted in the problem, and the stack is once k–, so the string will not be sorted from small to large, depending on whether k is large enough. When the number of k is used up, the following characters are considered There is no way to get out of the stack if the characters at the top of the stack are small.

4. There is a special case of using the stack, that is, the strings have been sorted, for example: num = "123456789", k = 3; then there is no way to pop the stack, the string we get is too long, so To determine whether the length of the string is too long, if it is too long, remove the following k characters, "123456789", remove the last 3, and leave "123456", the smallest.

5. You need to take out the string and then reverse the order in order to use the stack. Because it comes out first, of course, you must also determine whether the highest bit is 0, and whether it is all 0.

The code is as follows 2:

string removeKdigits(string num, int k) {
        if(num.size()<=k){//长度小于等于k则直接返回“0”
            return "0";
        }
        stack<char>s;
        s.push(num[0]);
        for(int i=1;i<num.size();i++){
        	 while(!s.empty()&&k!=0&&s.top()>num[i]){
        	 //栈空或者k的次数用完了或者栈顶最小则不用进入while
        	 	s.pop();//出栈
        	 	k--;//次数减一
			 }
			 s.push(num[i]);
		}
		string ss;
		while(!s.empty()){//提取字符
			ss+=s.top();
			s.pop();
		}
		reverse(ss.begin(),ss.end());//逆序
		int i=0;
		while(ss[i]=='0'){//跳过最高位为0
			i++;
		}
		ss=ss.substr(i);
		if(ss.size()==0){//全为0
			return "0";
		}
		if(ss.size()>n){//长度过长
			return ss.substr(0,n);
		}
		return ss;
    }
Published 14 original articles · Like 10 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/Milan_1in/article/details/105544984