02-JZ4 二维数组中的查找

我的

想法:

  1. 暴力:按行遍历,比较---O(m*n)
  2. 折半:行折半查找;有n行,折半n次---- O(nlgn)

问题:

不满足时间复杂度O(m+n)

正确

思路:

  1. 左下角开始比较
  2. arr[i][0]>target--往小找,往上走,i--;
  3. arr[i][0]<target--往大找,往右走,j++;
  4. arr[i][0]==target,即找到
  5. 循环截至条件,超出数组边界

适用场景:

迷宫遍历四周:因为行,列有序,会有方向的去遍历

代码

//1暴力方法
//题目:
/*
* 学习到:
* ------写代码
* 1. vector二维数组就像是一个元素为一维数组的数组:arr.size()是二维数组的行数,arr[0].size()是每行的元素个数
* 2. 将普通二维数组给vector容器赋值:matrix.push_back(a[i], a[i]+3);
* 3. vector成员函数push_back的使用,参数可以是值,也可以是迭代器
*/
#include <iostream>
using namespace std;
#include <vector>
//解决方法
class Solution1
{
public:
	//方法
	//返回目标值的有无,target是否在二维数组中
	bool find(vector<vector<int>> array, int target) {
		for (int i = 0; i < array.size(); i++) {
			if (array[i][0] > target) {
				break;
			}

			for (int j = 0; j < array[0].size(); j++) {
				if (array[i][j] == target) {
					return true;
				}
				else if (array[i][j] > target) {
					break;
				}
			}
		}
		return false;
	}

};
//没有返回值--打印二维数组
void printMatrix(const vector<vector<int>> matrix) {
	int m = matrix.size();
	int n = matrix[0].size();

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			cout << matrix[i][j] << " ";
		}
		cout << endl;
	}
}
//主函数
int main1()
{
	int a[][4] = { {1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15} };
	int target = 0;
	vector<vector<int>> nums;
	for (int i = 0; i < 4; i++) {
		nums.push_back(vector<int>(a[i], a[i] + 4));
	}

	//printMatrix(nums);
	
	Solution1 solution;

	cout << solution.find(nums, 14) << endl;

	return 0;
}
//分割线----------

//2折半法
//题目:
#include <iostream>
using namespace std;
#include <vector>
//解决方法
class Solution3
{
public:
	//方法
	bool find(int target, vector<vector<int>> nums) {
		for (int i = 0; i < nums.size(); i++) {
			int low = 0;
			int high = nums.size() - 1;
			while (low <= high) {
				int mid = (low + high) / 2;
				if (nums[i][mid] == target) {
					return true;
				}
				
				if (nums[i][mid] > target) {
					high = mid - 1;
					continue;
				}

				if (nums[i][mid] < target) {
					low = mid + 1;
					continue;
				}
			}
		}
		return false;
	}

};
//主函数
int main3()
{
	//测试
	int a[][4] = { {1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15} };	 //4*4
	int target = 7;		//目标值
	//创建vector二维数组容器
	vector<vector<int>> nums;
	//使用迭代器循环赋值
	for (int i = 0; i < 4; i++) {
		nums.push_back(vector<int>(a[i], a[i] + 4));
	}

	Solution3 solution;	//对象实例化

	cout << solution.find(target, nums) << endl;	//输出结果

	return 0;
}

//----分割线
//3. 数组O(m+n)遍历法
//题目:
/*
* 学习到:
* 代码------
* 1. 行,列数:rowCount, colCount
* 2. Solution类在全局区,多个文件相同类或函数会冲突
* 3. 代码调试,一定是自己错了,不要怀疑其他的。函数没执行,需要跳出本类的函数思维限制,去找其他的可能出现错误的地方
* 思路------
* 1. 先缕清执行一次的流程
* 2. 再思考循环,循环条件,变量维护
* 3. 再思考特殊情况
* 4. 再思考通用代码编写
*/
#include <iostream>
using namespace std;
#include <vector>
//解决方法
class Solution2
{
public:
	//方法
	//返回0or1,代表target是否在该数组中
	bool find(int target, vector<vector<int>> nums) {
		//行,列数
		int rowCount = nums.size();
		int colCount = nums[0].size();
		//cout << 2 << endl;
		//最初比较的元素下标值
		int i = rowCount - 1;
		int j = 0;
		//循环:元素与目标值大小
		while (i >= 0 && j < colCount) {
			if (nums[i][j] > target) {
				i--;
			}
			else if (nums[i][j] < target){
				j++;
			}
			else {
				return true;
			}
		}

		return false;
	}

};
//主函数
int main()
{
	//测试
	int a[][4] = { {1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15} };	 //4*4
	int target = 7;		//目标值
	//创建vector二维数组容器
	vector<vector<int>> nums;
	//使用迭代器循环赋值
	for (int i = 0; i < 4; i++) {
		nums.push_back(vector<int>(a[i], a[i] + 4));
	}

	Solution2 solution;	//对象实例化

	cout << solution.find(target, nums) << endl;	//输出结果

	return 0;
}



学习到

------写代码过程

  1. vector二维数组就像是一个元素为一维数组的数组:arr.size()是二维数组的行数,arr[0].size()是每行的元素个数
  2. 将普通二维数组给vector容器赋值:matrix.push_back(a[i], a[i]+3);
  3. vector成员函数push_back的使用,参数可以是值,也可以是迭代器
  4. 行,列数:rowCount, colCount

------调试过程

  1. 多文件编写时,全局区创建的几个类名,以及成员方法名相同,会造成主函数调用方法不确定是哪一个的问题----类名or成员方法名需要有区别
    Solution类在全局区,多个文件相同类或函数会冲突
  2. 调试需要静下心来去思考,然后再行动;需要精准察觉问题所在

-----——代码经验

  • 思路------
    1. 先缕清执行一次的流程
    1. 再思考循环,循环条件,变量维护
    1. 再思考特殊情况
    1. 再思考通用代码编写
posted @   行至为成  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示