1. 程式人生 > >//楊氏矩陣 有一個二維陣列. 陣列的每行從左到右是遞增的,每列從上到下是遞增的. 在這樣的陣列中查詢一個數字是否存在

//楊氏矩陣 有一個二維陣列. 陣列的每行從左到右是遞增的,每列從上到下是遞增的. 在這樣的陣列中查詢一個數字是否存在

題目:

//楊氏矩陣  有一個二維陣列.  陣列的每行從左到右是遞增的,每列從上到下是遞增的.  在這樣的陣列中查詢一個數字是否存在。  時間複雜度小於O(N);  陣列:  1 2 3  2 3 4  3 4 5  1 3 4  2 4 5  4 5 6

分析:拿到這個題一開始的思路就是暴力解法,直接兩個巢狀的for迴圈遍歷二維陣列,但是這樣的時間複雜度就是O^2(n),題目要求的時間複雜度是O(n),所以這種方法排除。換個思路:首先觀察這個二維陣列中元素的排列規律,因為它是從左到右,從上到下依次遞增的,這時候你有沒有想到什麼?和二分查詢很像吧,同樣是一個有序序列,只不過是二維陣列。沒關係,我們依然可以把二分查詢的思想用到這裡來。

從最右上角的那個資料開始查詢,每次只需要將data與其進行比較,即可去掉一行(or一列),不斷縮小比較範圍。直到最後找到對應值。具體程式碼也不難,我們需要做的就是不斷更新待查詢行和列。

本題關鍵點:

(1)如何返回兩個值(採用封裝成結構體的方式或者傳入指標帶入返回值)

(2)二分查詢思想的靈活運用

程式碼:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
//因為要返回位置座標(兩個值),考慮到函式只能有一個返回值,所以這裡採用了封裝成結構體的方式
typedef struct Position
{
	int x;
	int y;
}Position;
Position FindNum(int(*arr)[COL],int data)
{
	//從最右上角開始查詢,如果找到就返回對應位置座標,沒找到對應的座標則為-1,-1
	Position p;
	p.x = -1;
	p.y = -1;
	int row = 0;
	int col = COL - 1;
	while (row < ROW&&col >= 0)
	{
		if (data == arr[row][col])
		{
			p.x = row;
			p.y = col;
			return p;
		}
		else if (data>arr[row][col])
		{
			row++;
		}
		else
		{
			col--;
		}
	}
	return p;
}

int main()
{
	int arr[ROW][COL] = { { 1, 2, 3 }, { 4, 5, 6 },{ 7, 8, 9 } };
	int key = 0;
	printf("請輸入要查詢的數字:");
	scanf("%d", &key);
	Position p1=FindNum(arr, key);
	if (p1.x != -1 && p1.y != -1)
	{
		printf("找到了,下標為%d %d\n", p1.x, p1.y);
	}
	else
	{
		printf("不存在\n");
	}

	system("pause");
	return 0;
}

執行結果: