剑指offer - 二维数组中的查找
Posted darkchii
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer - 二维数组中的查找相关的知识,希望对你有一定的参考价值。
这题我总觉得 oj 有问题。。。就算真的复杂度很高,也不可能通不过一个样例吧。。。
第一眼没注意到每一列都从上到下递增,写出来的算法平均时间复杂度为 O(lgn * lgm),最坏为O(nlgm),思路就是对第一列做二分查找得到一个行区间,然后遍历行区间,对每一行做二分查找,但提交后有段错误(本地 MSVC 编译、运行没问题)。。。
然后又认真看一遍题之后,经过思考各种边界情况,优化了很多小地方的查找步数,时间复杂度肯定比第一个小很多,所以有点不敢相信居然超时?
class Solution { public: bool Find(int target, std::vector<std::vector<int>> array) { if (array.empty()) return false; if (array[0][0] > target) return false; if (array[array.size() - 1][array[0].size() - 1] < target) return false; int start_col = 0, end_col = array.size() - 1, mid_col = (start_col + end_col) / 2; while (array[start_col][0] < target && target < array[end_col][0]) { if (array[start_col][0] < target && target < array[mid_col][0]) start_col = (start_col + mid_col) / 2, end_col = mid_col, mid_col = (start_col + end_col) / 2; else if (array[mid_col][0] < target && target < array[end_col][0]) end_col = (mid_col + end_col) / 2, start_col = mid_col, mid_col = (start_col + end_col) / 2; else break; } for (int i = start_col; i <= end_col; i++) { int start_row = 0, end_row = array[0].size() - 1, mid_row = (start_row + end_row) / 2; if (array[i][start_row] == target) return true; if (array[i][end_row] == target) return true; while (start_row < end_row) { if (target == array[i][mid_row]) return true; else if (array[i][start_row] <= target && target <= array[i][mid_row]) start_row = (start_row + mid_row) / 2, end_row = mid_row, mid_row = (start_row + end_row) / 2; else if (array[i][mid_row] <= target && target <= array[i][end_row]) end_row = (mid_row + end_row) / 2, start_row = mid_row, mid_row = (start_row + end_row) / 2; else break; } } return false; } bool Find2(int target, std::vector<std::vector<int>> array) { int row = 0, col = 0; int row_siz = array.size(), col_siz = array[0].size(); while (row < row_siz && col < col_siz) { if (target == array[row][col]) return true; else if (col + 1 < col_siz && row + 1 < row_siz && target < array[row + 1][col + 1] && target > array[row + 1][col] && target > array[row][col + 1]) return false; else if (target < array[row][col]) { row--; if (row <= 0) return false; } if (col + 1 < col_siz && row + 1 < row_siz && target >= array[row + 1][col + 1]) col++, row++; else if (col + 1 < col_siz && target >= array[row][col + 1]) col++; else if (row + 1 < row_siz && target >= array[row + 1][col]) row++; else if (col + 1 < col_siz && target <= array[row][col + 1]) row--; else break; } return false; } };
以上是关于剑指offer - 二维数组中的查找的主要内容,如果未能解决你的问题,请参考以下文章