楼主: zhuli19901106
跳转到指定楼层
上一主题 下一主题
收起左侧

分享我的Lintcode题解,目前进度244/248

 
🔗
 楼主| zhuli19901106 2015-7-25 00:17:49 | 只看该作者
全局:
Sliding Window Median
题意:hard难度。经过了Sliding Window Maximum之后,这题就简单多了。
解法:在那题里我就说了,用map,也就是平衡树可以有效地求可变数组的最小值、最大值、中位数。具体怎么求中位呢?把大小为K的窗口分两半即可。类似的问题还有这个:“向一个空数组中不断添加元素,每添加一个,就求一次中位数。”
这题可以用堆来做,对吧?但Sliding Window Median就不行。因为堆可以随意添加,却不能随意删除,也就是说删什么不由我们决定,而map就可以。
这道题的思路很清晰,但是动手写起来才发现也不简单,需要考虑周全。我出了一两次bug才通过。算是名副其实的hard难度。
代码:
  1. // <map> is a powerful magic
  2. #include <map>
  3. using namespace std;

  4. class Solution {
  5. public:
  6.     /**
  7.      * @param nums: A list of integers.
  8.      * @return: The median of the element inside the window at each moving
  9.      */
  10.     vector<int> medianSlidingWindow(vector<int> &nums, int k) {
  11.         small.clear();
  12.         large.clear();
  13.         ns = nl = 0;
  14.         
  15.         vector<int> ans;
  16.         vector<int> &a = nums;
  17.         int n = a.size();
  18.         if (n == 0 || k == 0) {
  19.             return ans;
  20.         }
  21.         
  22.         ns = nl = 0;
  23.         int s, l;
  24.         int i;
  25.         for (i = 0; i < k - 1; ++i) {
  26.             add(a[i]);
  27.         }
  28.         for (i = k - 1; i < n; ++i) {
  29.             add(a[i]);
  30.             ans.push_back(small.rbegin()->first);
  31.             remove(a[i - k + 1]);
  32.         }
  33.         return ans;
  34.     }
  35. private:
  36.     map<int, int> small, large;
  37.     int ns, nl;
  38.    
  39.     void del(map<int, int> &m, int x) {
  40.         --m[x];
  41.         if (m[x] == 0) {
  42.             m.erase(x);
  43.         }
  44.     }
  45.    
  46.     void adjust() {
  47.         if (small.empty() || large.empty()) {
  48.             return;
  49.         }
  50.         
  51.         int n1, n2;
  52.         n1 = small.rbegin()->first;
  53.         n2 = large.begin()->first;
  54.         if (n1 <= n2) {
  55.             return;
  56.         }
  57.         
  58.         del(small, n1);
  59.         ++small[n2];
  60.         
  61.         del(large, n2);
  62.         ++large[n1];
  63.     }
  64.    
  65.     void add(int x) {
  66.         if (ns == nl) {
  67.             ++small[x];
  68.             ++ns;
  69.         } else {
  70.             ++large[x];
  71.             ++nl;
  72.         }
  73.         adjust();
  74.     }
  75.    
  76.     void remove(int x) {
  77.         if (small.find(x) != small.end()) {
  78.             del(small, x);
  79.             --ns;
  80.         } else {
  81.             del(large, x);
  82.             --nl;
  83.         }
  84.         if (ns < nl) {
  85.             ++small[large.begin()->first];
  86.             del(large, large.begin()->first);
  87.             ++ns;
  88.             --nl;
  89.         } else if (ns > nl + 1) {
  90.             ++large[small.rbegin()->first];
  91.             del(small, small.rbegin()->first);
  92.             --ns;
  93.             ++nl;
  94.         }
  95.         adjust();
  96.     }
  97. };
复制代码
复杂度:时间O(N * log(K)),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 00:27:32 | 只看该作者
全局:
Trapping Rain Water II
题意:hard难度。把Trapping Rain Water扩展到三维,给定每个点(X,Y)的高度Z,求这个形状能存多少水。
解法:这题真难,我独立想了一个多小时,才发现自己把题目理解错了,然后又独立想了一个多小时,没思路。对于一维的问题,你可以只考虑左边右边的情况如何,但对于二维的问题,你不能仅仅考虑前后左右四个方向的情况。应该怎么考虑呢?这是水,可以流动,所以应该用BFS搜(要用BFS,因为这符合自然规律)。这个代码我是参考了github上其他人的做法,所以理解不深,无法讲清楚。注意其中BFS用的是堆,而不是队列,这是整个算法的核心。真心巧妙。
代码:
  1. // Think about the heap, why pick the lowest altitude?
  2. #include <algorithm>
  3. #include <queue>
  4. using namespace std;

  5. typedef struct Term {
  6.     int i, j, h;
  7.     Term(int _i = 0, int _j = 0, int _h = 0): i(_i), j(_j), h(_h) {}
  8.    
  9.     bool operator < (const Term &t) const {
  10.         return h > t.h;
  11.     }
  12. } Term;

  13. class Solution {
  14. public:
  15.     Solution() {
  16.         offset.resize(4, vector<int>(2));
  17.         offset[0][0] = +1;
  18.         offset[0][1] = 0;
  19.         offset[1][0] = -1;
  20.         offset[1][1] = 0;
  21.         offset[2][0] = 0;
  22.         offset[2][1] = +1;
  23.         offset[3][0] = 0;
  24.         offset[3][1] = -1;
  25.     }
  26.     /**
  27.      * @param heights: a matrix of integers
  28.      * @return: an integer
  29.      */
  30.     int trapRainWater(vector<vector<int> > &heights) {
  31.         v.clear();
  32.         
  33.         vector<vector<int> > &a = heights;
  34.         n = a.size();
  35.         m = n ? a[0].size() : 0;
  36.         if (n == 0 || m == 0) {
  37.             return 0;
  38.         }
  39.         
  40.         int i, j;
  41.         v.resize(n, vector<bool>(m, false));
  42.         for (i = 0; i < n; ++i) {
  43.             pq.push(Term(i, 0, a[i][0]));
  44.             v[i][0] = true;
  45.             pq.push(Term(i, m - 1, a[i][m - 1]));
  46.             v[i][m - 1] = true;
  47.         }
  48.         for (i = 0; i < m; ++i) {
  49.             pq.push(Term(0, i, a[0][i]));
  50.             v[0][i] = true;
  51.             pq.push(Term(n - 1, i, a[n - 1][i]));
  52.             v[n - 1][i] = true;
  53.         }
  54.         
  55.         Term t, t1;
  56.         int ans = 0;
  57.         while (!pq.empty()) {
  58.             t = pq.top();
  59.             pq.pop();
  60.             
  61.             for (i = 0; i < 4; ++i) {
  62.                 t1.i = t.i + offset[i][0];
  63.                 t1.j = t.j + offset[i][1];
  64.                 if (!inbound(t1.i, t1.j) || v[t1.i][t1.j]) {
  65.                     continue;
  66.                 }
  67.                 ans += max(0, t.h - a[t1.i][t1.j]);
  68.                 t1.h = max(t.h, a[t1.i][t1.j]);
  69.                 pq.push(t1);
  70.                 v[t1.i][t1.j] = true;
  71.             }
  72.         }
  73.         
  74.         return ans;
  75.     }
  76. private:
  77.     vector<vector<int> > offset;
  78.     int n, m;
  79.     priority_queue<Term> pq;
  80.     vector<vector<bool> > v;
  81.    
  82.     bool inbound(int x, int y) {
  83.         return x >= 0 && x <= n - 1 && y >= 0 && y <= m - 1;
  84.     }
  85. };
复制代码
复杂度:时间O(N * M * log(N * M)),空间O(N * M)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 00:57:56 | 只看该作者
全局:
Expression Evaluation
题意:hard难度。给定一个已经分割好的算术表达式,求值。
解法:首先,看见这题我就改python了,用C++感觉太麻烦。python里的正则和lambda函数能派上用场。这题要处理的难点有两点,一是括号,二是优先级处理。具体的处理方法可以网上搜。我在搜之前,完全不知道该怎么干。剩下的就是实现了,参见代码。符号优先级不要用硬编码的方式处理,写一堆if elif是很低效的,直接把优先级定义成一个数值,就可以一套逻辑统一处理了。所谓代码与配置分离嘛。
这题存在非法case,感觉不合理。
代码:
  1. # There're some illegal cases, it's unfair
  2. import re

  3. class Solution:
  4.     # Define the precedence of operators
  5.     __pre = {}
  6.     __fun = {}
  7.    
  8.     def __init__(self):
  9.         pre_count = -1
  10.         
  11.         self.__pre['('] = pre_count
  12.         pre_count += 1
  13.         
  14.         self.__pre['+'] = pre_count
  15.         self.__pre['-'] = pre_count
  16.         pre_count += 1
  17.         
  18.         self.__pre['*'] = pre_count
  19.         self.__pre['/'] = pre_count
  20.         self.__pre['%'] = pre_count
  21.         pre_count += 1
  22.         
  23.         self.__fun['+'] = lambda x, y: x + y
  24.         self.__fun['-'] = lambda x, y: x - y
  25.         self.__fun['*'] = lambda x, y: x * y
  26.         self.__fun['/'] = lambda x, y: x / y
  27.         self.__fun['%'] = lambda x, y: x % y
  28.         
  29.     # @param expression: a list of strings;
  30.     # @return: an integer
  31.     def evaluateExpression(self, expression):
  32.         if (len(expression) == 0):
  33.             return 0
  34.         
  35.         num = []
  36.         op = []
  37.         for token in expression:
  38.             if re.match(r'[+\-]?\d+', token):
  39.                 num.append(int(token))
  40.             elif token == '(':
  41.                 op.append(token)
  42.             elif token == ')':
  43.                 while op[-1] != '(':
  44.                     self.__calculate(num, op)
  45.                 op.pop()
  46.             else:
  47.                 while len(op) > 0 and self.__pre[op[-1]] >= self.__pre[token]:
  48.                     self.__calculate(num, op)
  49.                 op.append(token)
  50.         while len(op) > 0:
  51.             self.__calculate(num, op)
  52.         
  53.         return num.pop() if len(num) > 0 else 0
  54.         
  55.     def __calculate(self, num, op):
  56.         n2 = num.pop()
  57.         n1 = num.pop()
  58.         single_op = op.pop()
  59.         num.append(self.__fun[single_op](n1, n2))
  60.         
复制代码
复杂度:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:01:05 | 只看该作者
全局:
Permutation Sequence
题意:给出长度为N的全排列中,字典序第K位的那个。
解法:考虑问题和子问题的关系。
代码:
  1. class Solution {
  2. public:
  3.     /**
  4.       * @param n: n
  5.       * @param k: the kth permutation
  6.       * @return: return the k-th permutation
  7.       */
  8.     string getPermutation(int n, int k) {
  9.         string ans = "";
  10.         --k;
  11.         vector<int> v;
  12.         int f = 1;
  13.         int i, j;
  14.         for (i = 1; i < n; ++i) {
  15.             f *= i;
  16.         }
  17.         
  18.         v.resize(n);
  19.         for (i = 0; i < n; ++i) {
  20.             v[i] = i;
  21.         }
  22.         
  23.         int p;
  24.         for (i = n - 1; i >= 1; --i) {
  25.             p = k / f;
  26.             k %= f;
  27.             ans.push_back('1' + v[p]);
  28.             for (j = p; j < i; ++j) {
  29.                 v[j] = v[j + 1];
  30.             }
  31.             v.pop_back();
  32.             f /= i;
  33.         }
  34.         ans.push_back('1' + v[0]);
  35.         return ans;
  36.     }
  37. };
复制代码
复杂度:时间O(N ^ 2),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:07:32 | 只看该作者
全局:
Count of Smaller Number
题意:给定一个数组,每次query给定一个数target,求出数组中小于target的元素的个数。
解法:因为数组本身不会变,所有直接排好序二分搜索即可。(这种题用线段树不是画蛇添足么)
代码:
  1. #include <algorithm>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.    /**
  6.      * @param A: An integer array
  7.      * @return: The number of element in the array that
  8.      *          are smaller that the given integer
  9.      */
  10.     vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) {
  11.         int n = queries.size();
  12.         int i, j;
  13.         vector<int> ans;
  14.         
  15.         sort(A.begin(), A.end());
  16.         for (i = 0; i < n; ++i) {
  17.             j = lower_bound(A.begin(), A.end(), queries[i]) - A.begin();
  18.             ans.push_back(j);
  19.         }
  20.         return ans;
  21.     }
  22. };
复制代码
复杂度:时间O((N + K) * log(N)),空间O(1)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:11:38 | 只看该作者
全局:
Building Outline
题意:hard难度。
解法:真难。我都懒得解释了,独立想了两个多钟头才想出来。最终确定了用map的解法。注意解法的思路在于把每个建筑的开始和结束分开想,随时关注最大高度是否发生了变化,一旦变化了,就说明轮廓有拐角了。
代码:
  1. #include <algorithm>
  2. #include <map>
  3. using namespace std;

  4. struct Term {
  5.     int x, y;
  6.     int op;
  7.     bool operator < (const Term &t) const {
  8.         if (x != t.x) {
  9.             return x < t.x;
  10.         }
  11.         if (op != t.op) {
  12.             return op < t.op;
  13.         }
  14.         if (op == 0) {
  15.             // Start of a building
  16.             return y > t.y;
  17.         } else {
  18.             // End of a building
  19.             return y < t.y;
  20.         }
  21.     }
  22. };

  23. class Solution {
  24. public:
  25.     /**
  26.      * @param buildings: A list of lists of integers
  27.      * @return: Find the outline of those buildings
  28.      */
  29.     vector<vector<int> > buildingOutline(vector<vector<int> > &buildings) {
  30.         vector<vector<int> > &a = buildings;
  31.         vector<Term> v;
  32.         Term t;
  33.         int n = a.size();
  34.         int i;
  35.         for (i = 0; i < n; ++i) {
  36.             t.x = a[i][0];
  37.             t.y = a[i][2];
  38.             t.op = 0;
  39.             v.push_back(t);
  40.             t.x = a[i][1];
  41.             t.y = a[i][2];
  42.             t.op = 1;
  43.             v.push_back(t);
  44.         }
  45.         sort(v.begin(), v.end());
  46.         
  47.         map<int, int> m;
  48.         vector<int> px, py;
  49.         bool b;
  50.         
  51.         m[0] = 1;
  52.         n = v.size();
  53.         for (i = 0; i < n; ++i) {
  54.             if (v[i].op == 0) {
  55.                 // Start of a building
  56.                 if (m.rbegin()->first < v[i].y) {
  57.                     px.push_back(v[i].x);
  58.                     py.push_back(v[i].y);
  59.                 }
  60.                 ++m[v[i].y];
  61.             } else {
  62.                 // End of a building
  63.                 b = false;
  64.                 --m[v[i].y];
  65.                 if (m[v[i].y] == 0) {
  66.                     b = v[i].y == m.rbegin()->first;
  67.                     m.erase(v[i].y);
  68.                 }
  69.                 if (b) {
  70.                     px.push_back(v[i].x);
  71.                     py.push_back(m.rbegin()->first);
  72.                 }
  73.             }
  74.         }
  75.         
  76.         n = px.size();
  77.         vector<vector<int> > ans;
  78.         vector<int> seg(3);
  79.         for (i = 0; i < n - 1; ++i) {
  80.             // Ignore all zeros
  81.             if (py[i] == 0) {
  82.                 continue;
  83.             }
  84.             seg[0] = px[i];
  85.             seg[1] = px[i + 1];
  86.             seg[2] = py[i];
  87.             ans.push_back(seg);
  88.         }
  89.         
  90.         return ans;
  91.     }
  92. };
复制代码
复杂度:时间O(N * log(N)),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:18:49 | 只看该作者
全局:
本帖最后由 zhuli19901106 于 2015-7-25 01:26 编辑

Convert Expression to Polish Notation
题意:hard难度。给定一个分割过的表达式,把它转化为波兰表达式。
解法:其实这题是为了帮助理解表达式树的作用。结合之前表达式求值那题,经过适当的修改,就可以用同样的方法构造出一棵表达式树,而表达式树的前序遍历就是波兰表达式。不建树应该也可以做,但是我觉得代码已经比较复杂了,如果还耗脑子写个非递归版的前序遍历,怕是要出bug,所以就不找麻烦了。
代码:
  1. import re
  2. '''
  3. Definition of ExpressionTreeNode:
  4. class ExpressionTreeNode:
  5.     def __init__(self, symbol):
  6.         self.symbol = symbol
  7.         self.left, self.right = None, None
  8. '''
  9. ETN = ExpressionTreeNode

  10. class Solution:
  11.     # Define the precedence of operators
  12.     __pre = {}
  13.     __fun = {}
  14.    
  15.     def __init__(self):
  16.         pre_count = -1
  17.         
  18.         self.__pre['('] = pre_count
  19.         pre_count += 1
  20.         
  21.         self.__pre['+'] = pre_count
  22.         self.__pre['-'] = pre_count
  23.         pre_count += 1
  24.         
  25.         self.__pre['*'] = pre_count
  26.         self.__pre['/'] = pre_count
  27.         self.__pre['%'] = pre_count
  28.         pre_count += 1
  29.         
  30.     # @param expression: A string list
  31.     # @return: The Polish notation of this expression
  32.     def convertToPN(self, expression):
  33.         if (len(expression) == 0):
  34.             return None
  35.         
  36.         num = []
  37.         op = []
  38.         for token in expression:
  39.             if re.match(r'[+\-]?\d+', token):
  40.                 num.append(ETN(token))
  41.             elif token == '(':
  42.                 op.append(token)
  43.             elif token == ')':
  44.                 while op[-1] != '(':
  45.                     self.__calculate(num, op)
  46.                 op.pop()
  47.             else:
  48.                 while len(op) > 0 and self.__pre[op[-1]] >= self.__pre[token]:
  49.                     self.__calculate(num, op)
  50.                 op.append(token)
  51.         while len(op) > 0:
  52.             self.__calculate(num, op)
  53.             
  54.         ans = []
  55.         root = num.pop() if len(num) > 0 else None
  56.         self.__preorder(root, ans)
  57.         return ans
  58.         
  59.     def __calculate(self, num, op):
  60.         n2 = num.pop()
  61.         n1 = num.pop()
  62.         single_op = ETN(op.pop())
  63.         single_op.left = n1
  64.         single_op.right = n2
  65.         num.append(single_op)
  66.         
  67.     def __preorder(self, root, ans):
  68.         if root == None:
  69.             return
  70.         ans.append(root.symbol)
  71.         self.__preorder(root.left, ans)
  72.         self.__preorder(root.right, ans)
  73.         
复制代码
复杂度:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:22:55 | 只看该作者
全局:
本帖最后由 zhuli19901106 于 2015-7-25 01:25 编辑

Convert Expression to Reverse Polish Notation
题意:hard难度。给定一个分割过的表达式,把它转化为逆波兰表达式。
解法:和上次波兰表达式一样,构造表达式树,然后进行后序遍历即可。
代码:
  1. import re
  2. '''
  3. Definition of ExpressionTreeNode:
  4. class ExpressionTreeNode:
  5.     def __init__(self, symbol):
  6.         self.symbol = symbol
  7.         self.left, self.right = None, None
  8. '''
  9. ETN = ExpressionTreeNode

  10. class Solution:
  11.     # Define the precedence of operators
  12.     __pre = {}
  13.     __fun = {}
  14.    
  15.     def __init__(self):
  16.         pre_count = -1
  17.         
  18.         self.__pre['('] = pre_count
  19.         pre_count += 1
  20.         
  21.         self.__pre['+'] = pre_count
  22.         self.__pre['-'] = pre_count
  23.         pre_count += 1
  24.         
  25.         self.__pre['*'] = pre_count
  26.         self.__pre['/'] = pre_count
  27.         self.__pre['%'] = pre_count
  28.         pre_count += 1
  29.         
  30.     # @param expression: A string list
  31.     # @return: The Reverse Polish notation of this expression
  32.     def convertToRPN(self, expression):
  33.         if (len(expression) == 0):
  34.             return None
  35.         
  36.         num = []
  37.         op = []
  38.         for token in expression:
  39.             if re.match(r'[+\-]?\d+', token):
  40.                 num.append(ETN(token))
  41.             elif token == '(':
  42.                 op.append(token)
  43.             elif token == ')':
  44.                 while op[-1] != '(':
  45.                     self.__calculate(num, op)
  46.                 op.pop()
  47.             else:
  48.                 while len(op) > 0 and self.__pre[op[-1]] >= self.__pre[token]:
  49.                     self.__calculate(num, op)
  50.                 op.append(token)
  51.         while len(op) > 0:
  52.             self.__calculate(num, op)
  53.             
  54.         ans = []
  55.         root = num.pop() if len(num) > 0 else None
  56.         self.__postorder(root, ans)
  57.         return ans
  58.         
  59.     def __calculate(self, num, op):
  60.         n2 = num.pop()
  61.         n1 = num.pop()
  62.         single_op = ETN(op.pop())
  63.         single_op.left = n1
  64.         single_op.right = n2
  65.         num.append(single_op)
  66.         
  67.     def __postorder(self, root, ans):
  68.         if root == None:
  69.             return
  70.         self.__postorder(root.left, ans)
  71.         self.__postorder(root.right, ans)
  72.         ans.append(root.symbol)
  73.         
复制代码
复杂度:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:29:32 | 只看该作者
全局:
Expression Tree Build
题意:hard难度。给定一个分割过的算术表达式,构造表达式树。
解法:教学题。还是根据表达式求值那题的处理思路修改得来。总之,这些题的规则都是相同的。最好理解+记忆,这样面试遇到了才不会抓瞎。
代码:
  1. import re
  2. """
  3. Definition of ExpressionTreeNode:
  4. class ExpressionTreeNode:
  5.     def __init__(self, symbol):
  6.         self.symbol = symbol
  7.         self.left, self.right = None, None
  8. """
  9. ETN = ExpressionTreeNode

  10. class Solution:
  11.     # Define the precedence of operators
  12.     __pre = {}
  13.     __fun = {}
  14.    
  15.     def __init__(self):
  16.         pre_count = -1
  17.         
  18.         self.__pre['('] = pre_count
  19.         pre_count += 1
  20.         
  21.         self.__pre['+'] = pre_count
  22.         self.__pre['-'] = pre_count
  23.         pre_count += 1
  24.         
  25.         self.__pre['*'] = pre_count
  26.         self.__pre['/'] = pre_count
  27.         self.__pre['%'] = pre_count
  28.         pre_count += 1
  29.         
  30.     # @param expression: A string list
  31.     # @return: The root of expression tree
  32.     def build(self, expression):
  33.         if (len(expression) == 0):
  34.             return None
  35.         
  36.         num = []
  37.         op = []
  38.         for token in expression:
  39.             if re.match(r'[+\-]?\d+', token):
  40.                 num.append(ETN(token))
  41.             elif token == '(':
  42.                 op.append(token)
  43.             elif token == ')':
  44.                 while op[-1] != '(':
  45.                     self.__calculate(num, op)
  46.                 op.pop()
  47.             else:
  48.                 while len(op) > 0 and self.__pre[op[-1]] >= self.__pre[token]:
  49.                     self.__calculate(num, op)
  50.                 op.append(token)
  51.         while len(op) > 0:
  52.             self.__calculate(num, op)
  53.         return num.pop() if len(num) > 0 else None
  54.         
  55.     def __calculate(self, num, op):
  56.         n2 = num.pop()
  57.         n1 = num.pop()
  58.         single_op = ETN(op.pop())
  59.         single_op.left = n1
  60.         single_op.right = n2
  61.         num.append(single_op)
  62.         
复制代码
复杂度:时间O(N),空间O(N)。
回复

使用道具 举报

🔗
 楼主| zhuli19901106 2015-7-25 01:33:14 | 只看该作者
全局:
Valid Sudoku
题意:给定一个数独,检查是否有效。只要不存在冲突,就算有效。数独规则就不说了。
解法:按规则检查即可。
代码:
  1. #include <cmath>
  2. using namespace std;

  3. class Solution {
  4. public:
  5.     /**
  6.       * @param board: the board
  7.       * @return: wether the Sudoku is valid
  8.       */
  9.     bool isValidSudoku(const vector<vector<char> >& board) {
  10.                 int n2 = board.size();
  11.                 int n = (int)sqrt(n2);
  12.                 vector<vector<bool> > row;
  13.                 vector<vector<bool> > col;
  14.                 vector<vector<bool> > block;
  15.                
  16.                 row.resize(n2, vector<bool>(n2, false));
  17.                 col.resize(n2, vector<bool>(n2, false));
  18.                 block.resize(n2, vector<bool>(n2, false));
  19.                
  20.                 int i, j;
  21.                 int idx;
  22.                 for (i = 0; i < n2; ++i) {
  23.                         for (j = 0; j < n2; ++j) {
  24.                                 if (board[i][j] == '.') {
  25.                                         continue;
  26.                                 }
  27.                                 idx = board[i][j] - '1';
  28.                                 if (row[i][idx]) {
  29.                                         return false;
  30.                                 }
  31.                                 row[i][idx] = true;
  32.                                 if (col[j][idx]) {
  33.                                         return false;
  34.                                 }
  35.                                 col[j][idx] = true;
  36.                                 if (block[i / n * n + j / n][idx]) {
  37.                                         return false;
  38.                                 }
  39.                                 block[i / n * n + j / n][idx] = true;
  40.                         }
  41.                 }
  42.                 return true;               
  43.     }
  44. };
复制代码
复杂度:时间O(N ^ 2),空间O(N ^ 2)。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表