LeetCode Weekly 225

  1. 不熟练,思考时间太长
  2. 看题的时候在脑子里形成动画

5662. 满足三条件之一需改变的最少字符数

前两个条件的意思是:我们对a和b进行修改后,使得a,b中的字符在某个字符边界('a'-'z')的两侧。为了得到最小值,我们可以去枚举边界然后进行判定,取最小值。然后在与条件三的结果取最小值就ok啦

class Solution {
public:
    int minCharacters(string a, string b) {
        int n = a.size(), m = b.size();
        vector<int> cnt_a(26,0), cnt_b(26,0);
        int ans = m+n;
        for (int i = 0; i <= 24; i++){//枚举边界
            int left = 'a'+i, right = 'a'+i+1;
            int cur1 = 0, cur2 = 0;
            //边界已经确定了,我们检查一下a,b有多少个字符在边界外
 			//a可以在边界的左侧,也可以在右侧; b同理
            for (int j = 0; j < n; j++){
                if (a[j] > left) cur1++; // left
                if (a[j] < right) cur2++; // right
            }
            for (int j = 0; j < m; j++){
                if (b[j] > left) cur2++;
                if (b[j] < right) cur1++;
            }
            ans = min(ans, min(cur1, cur2));
        }
        //条件三
        for (int i = 0; i < n; i++) cnt_a[a[i]-'a']++;
        for (int i = 0; i < m; i++) cnt_b[b[i]-'a']++;
        for (int i = 0; i < 26; i++){
            int cur1 = n-cnt_a[i] + m-cnt_b[i];
            ans = min(ans, cur1);
        }
        return ans;
    }
};

5664. 放置盒子

想要盒子挨地最少,那么挨地盒子数肯定有下面的规律(成阶梯状):

情形 按着地面盒子数 这种情况下能放盒子总数
情形1 1 = 1(只放一个) 1
情形2 2+1 = 3(第一行放两个,第二行放一个) 3+1(上面可以托起一个)
情形3 3+2+1 = 6 6+3+1(上面情形中所有的接地盒子数之和)
..... ..... .....
情形n n+n-1+...1 = (n+n2)/2 > n(这个可以看出,这样阶梯状放,就算全挨地,也能放下n个盒子) .....

上面讨论的是极端情况,现在考虑一下变化过程:

假如接地3+2+1个盒子 向 4+3+2+1 个盒子过渡,我们在地面上添一个盒子,总共就只能放一个盒子;我们在地面上添两个盒子,那总共我们就能放2+1个盒子(上面可以顶起来一个);如果地面加三个,那总共就可以放3+2+1个盒子.....

我们考虑哪种极端条件放置的盒子总数刚好小于n,然后在地面逐个加盒子,进行判断就ok了

class Solution {
public:
    int minimumBoxes(int n) {
        int idx, sum = 0, base = 0;
        for (idx = 1; ; idx++){
            base += idx;
            sum += base;
            if (sum >= n) break;
        }
     	//现在的极端条件是sum刚好大于等于n
        int ans = 0;
        for (int i = 1; i <= idx; i++) ans += i;
        if (sum == n) return ans; //如果等于n,那就是极端条件下的接地盒子数
        else ans -= idx;//否则我们要变到前面一个极端条件
        for (int j = idx; j >= 1; j--) sum -= j;
        
        //进行过渡判断
        int cur_sum = 0;
        for (int i = 1; i <= idx; i++){
            cur_sum += i;
            if (cur_sum+sum >= n){
                ans += i;
                break;
            }
        }
        return ans;
        
    }
};
"没有天赋异禀,那就加倍努力"
原文地址:https://www.cnblogs.com/Beic233/p/14323041.html