【剑指Offer】【数组】4_二维数组中的查找
题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
1 | 2 | 8 | 9 |
2 | 4 | 9 | 12 |
4 | 7 | 10 | 13 |
6 | 8 | 11 | 15 |
假设:要查找数字7
A1:如果一个一个比较的话时间复杂度是O(n2)
A2:首先选取数组中右上角的数字 (也可以选取左下角数字,大于剔除行,小于剔除列)
如果该数字等于target则返回true,查找结束
如果该数字大于target,则剔除这个数字所在的列(因为右上的数字是列中最小的,等于该列的所有数都大于target)
如果该数字小于target,则剔除这个数字所在的行(因为target可能在该数字的列中)
时间复杂度O(n)
//右上角
class Solution { public: bool Find(int target, vector<vector<int> > array) { if(array.empty()) { return false; } int row = 0; int col = array[0].size() - 1;
while((row < array.size()) && (col >= 0)) { if(array[row][col] == target) { return true; } else if(array[row][col] > target) { col--; } else { row++; } } return false; } };
//左下角
class Solution { public: bool Find(int target, vector<vector<int> > array) { if(array.empty()) { return false; } int row = array.size() - 1; int col = 0; while((row >=0) && (col < array[0].size())) { if(array[row][col] == target) { return true; } else if(array[row][col] < target) { col++; } else { row--; } } return false; } };
Q:为什么不选择左上角/右下角?
A:如果查找7,选择左上角1,1小于7,但是1是所在列元素中最小的,所以7有可能在1的所在列,不能剔除该列;1是所在行中最小的,7有可能在1所在行,不能剔除改行。无法缩小查找范围(选择右下角数同理)
相关题目:
回文数组:输入一个正整数组成的数组,要求你插入一些数字,使其变为回文的数组,且数组中所有数字的和尽可能小。输出这个插入后数组中元素的和。
数组操作:输入一个无序整数数组,调整数组中数字的顺序, 所有偶数位于数组的前半部分,使得所有奇数位于数组的后半部分。要求时间复杂度为O(n)。
中位数:小M给你一个长度为n的数组,我们定义median数为该数组从小到大排序后,下标为(n-1)/2的数字。下标从0开始,(n-1)/2表示整数除法,即向下取整。现在我们已经得到了一个初始的数组,我们希望这个数组的median数是一个给定数字x。所以我们需要加入一些数到数组中从而完成我们的目标。数组中的元素可以重复,请问,最少需要加入多少个数字才能达成这个目标。