竞赛196

所有蚂蚁掉下来前的最后一刻

有一块木板,长度为 n 个 单位 。一些蚂蚁在木板上移动,每只蚂蚁都以 每秒一个单位 的速度移动。其中,一部分蚂蚁向 左 移动,其他蚂蚁向 右 移动。

当两只向 不同 方向移动的蚂蚁在某个点相遇时,它们会同时改变移动方向并继续移动。假设更改方向不会花费任何额外时间。

而当蚂蚁在某一时刻 t 到达木板的一端时,它立即从木板上掉下来。

给你一个整数 n 和两个整数数组 left 以及 right 。两个数组分别标识向左或者向右移动的蚂蚁在 t = 0 时的位置。请你返回最后一只蚂蚁从木板上掉下来的时刻。

 

示例 1:

 

 

输入:n = 4, left = [4,3], right = [0,1]
输出:4
解释:如上图所示:

 

 


-下标 0 处的蚂蚁命名为 A 并向右移动。
-下标 1 处的蚂蚁命名为 B 并向右移动。
-下标 3 处的蚂蚁命名为 C 并向左移动。
-下标 4 处的蚂蚁命名为 D 并向左移动。
请注意,蚂蚁在木板上的最后时刻是 t = 4 秒,之后蚂蚁立即从木板上掉下来。(也就是说在 t = 4.0000000001 时,木板上没有蚂蚁)。
示例 2:

 

输入:n = 7, left = [], right = [0,1,2,3,4,5,6,7]
输出:7
解释:所有蚂蚁都向右移动,下标为 0 的蚂蚁需要 7 秒才能从木板上掉落。
示例 3:

 

输入:n = 7, left = [0,1,2,3,4,5,6,7], right = []
输出:7
解释:所有蚂蚁都向左移动,下标为 7 的蚂蚁需要 7 秒才能从木板上掉落。
示例 4:

输入:n = 9, left = [5], right = [4]
输出:5
解释:t = 1 秒时,两只蚂蚁将回到初始位置,但移动方向与之前相反。
示例 5:

输入:n = 6, left = [6], right = [0]
输出:6
 

提示:

1 <= n <= 10^4
0 <= left.length <= n + 1
0 <= left[i] <= n
0 <= right.length <= n + 1
0 <= right[i] <= n
1 <= left.length + right.length <= n + 1
left 和 right 中的所有值都是唯一的,并且每个值 只能出现在二者之一 中。

代码.....待完善

 

总结:这个第二题,当时一看竟然没思路,后来偶然间作出最后一道题,然后就花了1个多小时做第三题,一直没做出了,早知道就做第二题,直接排进前200 名。天呐!!!

 

统计全 1 子矩形

给你一个只包含 0 和 1 的 rows * columns 矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。

 

示例 1:

输入:mat = [[1,0,1],
  [1,1,0],
  [1,1,0]]
输出:13
解释:
有 6 个 1x1 的矩形。
有 2 个 1x2 的矩形。
有 3 个 2x1 的矩形。
有 1 个 2x2 的矩形。
有 1 个 3x1 的矩形。
矩形数目总共 = 6 + 2 + 3 + 1 + 1 = 13 。
示例 2:

输入:mat = [[0,1,1,0],
  [0,1,1,1],
  [1,1,1,0]]
输出:24
解释:
有 8 个 1x1 的子矩形。
有 5 个 1x2 的子矩形。
有 2 个 1x3 的子矩形。
有 4 个 2x1 的子矩形。
有 2 个 2x2 的子矩形。
有 2 个 3x1 的子矩形。
有 1 个 3x2 的子矩形。
矩形数目总共 = 8 + 5 + 2 + 4 + 2 + 2 + 1 = 24 。
示例 3:

输入:mat = [[1,1,1,1,1,1]]
输出:21
示例 4:

输入:mat = [[1,0,1],[0,1,0],[1,0,1]]
输出:5
 

提示:

1 <= rows <= 150
1 <= columns <= 150
0 <= mat[i][j] <= 1

 

class Solution {
    public int numSubmat(int[][] mat) {
        int row = mat.length, col = mat[0].length, ans = 0;

        for (int i = 0; i < row; i++){
            //统计
            for (int j = i; j < row; j++){
                int now = 0;
                for (int k = 0; k < col; k++){
                    if (mat[j][k] == 0) now = 0;
                    else now = k == 0 ? mat[j][0] : (now + 1);
                    ans += now;
                }
            }
            //压缩
            for (int j = row - 1; j > i; j--){
                for (int k = 0; k < col; k++){
                    mat[j][k] = mat[j][k] & mat[j - 1][k];
                }
            }
        }
        return ans;
    }
}

  总结:

这可能是我看到最经典的了,首先在统计每一行矩形的时候,用到了等差数列。

其次在统计不是一行的数据时,使用了,从合并矩形的思路。

而我当时的思路也只能是从某个点出发,先统计一行的矩形,其次统计竖着的矩形,就不会统计了,写了1个多小数没个应。

/**
 * @param {number[][]} mat
 * @return {number}
 */
var numSubmat = function(mat) {
    let len = mat.length;
    let width = mat[0].length;
    let sum = 0;
    for(let j=0; j<len; j++){
        for(let i=0; i<width; i++){
            if(mat[j][i] ===1){
                // sum++;
                // mat[j][i] = -1
                let ss=i;
                while(i>=0){
                    if(mat[j][--i]) {
                        ss = i
                    }else {
                        break
                    }
                }
                // let ss = mat[j].find(f=>f!==0)
                if(mat[j][ss]){
                   sum++; 
                    mat[j][ss] = -1
                }
                for(let s=ss+1; s<width; s++){
                    if(mat[j][s]){
                       sum++;
                        mat[j][s] = -1
                        for(let sj = j+1; sj<len; sj++){
                            if(mat[sj].slice(ss, s+1).every(e=>e!==0)){
                               sum++; 
                               for(let tt = ss; tt<s+1; tt++){
                                   mat[sj][tt] = -1
                               }
                            } else {
                                break
                            }
                        } 
                    } else {
                        break
                    }
                }
                // zuo
                // for(let s=i-1; s>=0; s--){
                //     if(mat[j][s]){
                //        sum++;
                //         mat[j][s] = -1
                //         for(let sj = j+1; j<len; sj++){
                //             if(mat[sj].slice(i, s+1).every(e=>e===1)){
                //                sum++; 
                //                for(let tt = i; tt<s+1; tt++){
                //                    mat[sj][tt] = -1
                //                }
                //             } else {
                //                 break
                //             }
                //         } 
                //     } else {
                //         break
                //     }
                // }
                // xia
                for(let s1 = j+1; s1<len; s1++){
                    if(mat[s1][ss]){
                        sum++;
                        mat[s1][ss] = -1
                    } else {
                        break
                    }
                }
                // shang
                // for(let s1 = j-1; s1>=0; s1--){
                //     if(mat[s1][i]){
                //         sum++;
                //         mat[s1][i] = -1
                //     } else {
                //         break
                //     }
                // }
            }
        }
    }
    return sum;
};

  

参考连接: https://leetcode-cn.com/problems/count-submatrices-with-all-ones/solution/bian-tong-ji-bian-ya-suo-xiang-xi-by-quantum-10/

最多 K 次交换相邻数位后得到的最小整数

给你一个字符串 num 和一个整数 k 。其中,num 表示一个很大的整数,字符串中的每个字符依次对应整数上的各个 数位 。

你可以交换这个整数相邻数位的数字 最多 k 次。

请你返回你能得到的最小整数,并以字符串形式返回。

 

示例 1:

 

输入:num = "4321", k = 4
输出:"1342"
解释:4321 通过 4 次交换相邻数位得到最小整数的步骤如上图所示。
示例 2:

输入:num = "100", k = 1
输出:"010"
解释:输出可以包含前导 0 ,但输入保证不会有前导 0 。
示例 3:

输入:num = "36789", k = 1000
输出:"36789"
解释:不需要做任何交换。
示例 4:

输入:num = "22", k = 22
输出:"22"
示例 5:

输入:num = "9438957234785635408", k = 23
输出:"0345989723478563548"
 

提示:

1 <= num.length <= 30000
num 只包含 数字 且不含有 前导 0 。
1 <= k <= 10^9

/**
 * @param {string} num
 * @param {number} k
 * @return {string}
 */

var minInteger = function(num, k) {
    num = num.split('')
    let len = num.length;
    let t=0;//t标记每次交换开始的首位置 
    let n,  min;
    while(k>0){
        if(t==len)
          break;
        n=t;//用n标记每次交换开始时的用于交换部分的首字符
        for(let i=t;i<=t+k;i++) {
            if(i>=len)
              break;
            if(num[i]<num[n])
              n=i;//遇到字符数小的字符时,用n标记下来。 
        }
        if(n!=t)
			{
				min=num[n];
				for(let i=n;i>t;i--)
				  num[i]=num[i-1];
				num[t]=min;
				k-=n-t;//等于k=k-(n-t);
			}
			t++;
        
        
    }
    return num.join('')
};

  

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/last-moment-before-all-ants-fall-out-of-a-plank
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

posted @ 2020-07-13 14:25  土豆zhang  阅读(164)  评论(0编辑  收藏  举报