• LeetCode刷题191118


      博主渣渣一枚,刷刷leetcode给自己瞅瞅,大神们由更好方法还望不吝赐教。题目及解法来自于力扣(LeetCode),传送门

    算法:

    给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

    示例 1:

    输入:
    [
    [ 1, 2, 3 ],
    [ 4, 5, 6 ],
    [ 7, 8, 9 ]
    ]
    输出: [1,2,3,6,9,8,7,4,5]
    示例 2:

    输入:
    [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9,10,11,12]
    ]
    输出: [1,2,3,4,8,12,11,10,9,5,6,7]

    解:

    public class Solution {
        public IList<int> SpiralOrder(int[][] matrix)
            {
                if (matrix.Length == 0)
                {
                    return new List<int>();
                }
    
                int minRow = 0;
                int minColumn = 0;
                int maxRow = matrix.GetLength(0) - 1;
                int maxColumn = matrix[0].GetLength(0) - 1;
    
                var seen = new List<List<bool>>();
    
                for (int i = 0; i <= maxRow; i++)
                {
                    var x = new List<bool>();
    
                    for (int j = 0; j <= maxColumn; j++)
                    {
                        x.Add(false);
                    }
    
                    seen.Add(x);
                }
    
                var dr = new int[] { 0, 1, 0, -1 };
                var dc = new int[] { 1, 0, -1, 0 };
    
                int r = 0, c = 0, di = 0;
    
                var result = new List<int>();
    
                for (int i = 0; i < (maxRow + 1) * (maxColumn + 1); i++)
                {
                    result.Add(matrix[r][c]);
                    seen[r][c] = true;
    
                    var nextr = r + dr[di];
                    var nextc = c + dc[di];
    
                    if (nextr >= 0 && nextr <= maxRow && nextc >= 0 && nextc <= maxColumn && !seen[nextr][nextc])
                    {
                        r = nextr;
                        c = nextc;
                    }
                    else
                    {
                        di = (di + 1) % 4;
                        r = r + dr[di];
                        c = c + dc[di];
                    }
                }
    
                return result;
            }
    }

      这道题说来惭愧,渣渣二狗一开始做出来的没有完全通过验证。仔细分析一下,重点在于解决“转向”所引发的问题。换句话说,如果单纯输出一行或一列,无论是正行或逆向都是很容易的。无非就是行索引或者列索引的自增或自减。上面的解法是官方给的一种思路。重点其实在于dr,dc,与di以及seen数组的定义。

      先来说说seen,这个数组是和要处理的数组matrix相同的规模,储存的内容表示对应的matrix节点有没有被访问过。当我们旋转行进的方向旋转了三次之后,放入result中的顺序其实是第一列由下自上的,这样再回到第[0][0]时,我们可以利用seen[0][0]判断出需要进行转向了。

      再来看看dr,dc与di。dr与dc可以理解为一个“向量”,表示当前在matrix中应该前进的方向。如第一组值,dr为0,dc为1,代表每次移动时向column的正向(→)移动。每当我们放入result中一个值之后,利用dr,dc与di来决定下一个要放入result中的值的行与列的索引。当行进至边界值时,我们获取到的新的索引nextr与nextc其实是不存在的,这时可以利用nextr与nextc与对应的边界进行比较来判断。一旦发生这种情况,我们就需要调整行进的方向,因此对di进行处理。

      二狗自己的代码想了想也决定贴出来,失败的原因在于两点:1.边界值没有好好想清楚,把问题复杂化。2.处理数据的逻辑与进行循环的变量交杂在一起,产生歧义与影响。

    public class Solution {
        public IList<int> SpiralOrder(int[][] matrix)
            {
                int minRow = 0;
                int minColumn = 0;
                int maxRow = matrix.GetLength(0) - 1;
                int maxColumn = matrix[0].GetLength(0) - 1;
    
                var seen = new List<List<bool>>();
    
                for (int i = 0; i <= maxRow; i++)
                {
                    var x = new List<bool>();
    
                    for (int j = 0; j <= maxColumn; j++)
                    {
                        x.Add(false);
                    }
    
                    seen.Add(x);
                }
    
                var dr = new int[] { 0, 1, 0, -1 };
                var dc = new int[] { 1, 0, -1, 0 };
    
                int r = 0, c = 0, di = 0;
    
                var result = new List<int>();
    
                for (int i = 0; i < (maxRow + 1) * (maxColumn + 1); i++)
                {
                    result.Add(matrix[r][c]);
                    seen[r][c] = true;
    
                    var nextr = r + dr[di];
                    var nextc = c + dc[di];
    
                    if (nextr >= 0 && nextr <= maxRow && nextc >= 0 && nextc <= maxColumn && !seen[nextr][nextc])
                    {
                        r = nextr;
                        c = nextc;
                    }
                    else
                    {
                        di = (di + 1) % 4;
                        r = r + dr[di];
                        c = c + dc[di];
                    }
                }
    
                return result;
            }
    }

    数据库:

    某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

    Customers 表:

    +----+-------+
    | Id | Name |
    +----+-------+
    | 1 | Joe |
    | 2 | Henry |
    | 3 | Sam |
    | 4 | Max |
    +----+-------+
    Orders 表:

    +----+------------+
    | Id | CustomerId |
    +----+------------+
    | 1 | 3 |
    | 2 | 1 |
    +----+------------+
    例如给定上述表格,你的查询应返回:

    +-----------+
    | Customers |
    +-----------+
    | Henry |
    | Max |
    +-----------+

     

    解:

      很简单,就exists的简单应用。

    select
    c.Name as Customers
    from Customers c
    where not exists
    (
      Select *
      from Orders o
      where o.CustomerId = c.Id
    )

      当然也可以用左连接或者not in的方式完成。

      

  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/dogtwo0214/p/11883709.html
Copyright © 2020-2023  润新知