每日刷题1118

Posted dogtwo0214

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日刷题1118相关的知识,希望对你有一定的参考价值。

  博主渣渣一枚,刷刷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的方式完成。

  

以上是关于每日刷题1118的主要内容,如果未能解决你的问题,请参考以下文章

每日刷题记录 (十三)

刷题的狂欢-----JAVA每日三练-----第四天

力扣刷题每日打卡

刷题5:每日温度

每日刷题3.135道算法+15道面试 - 阿V

力扣刷题每日打卡