杨氏矩阵是一个二维矩阵,特点是每一行的右边的元素比左边的大,每一列下面的元素比上面的大;

比如

1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15

假设要查找的变量为target,我刚开始的想法是先定位到target的纵坐标;先找到target可能所在的行,然后再在那行遍历横坐标;这种方法是最暴力的方法,而且所需的时间复杂度是O(m*n)显然不是一个好的做法;

考虑到杨氏矩阵的特性;先给一个比较的基准点;例如 第4行第4列的元素5,如果要查找的target比基准点大,那么是在基准点元素的右方或者下方;如果查找的点比基准点小,那么元素可能在元素的左方或者上方;这样就会出现元素重叠出现在两个区域的情况;

再仔细想想,有没有更好的方法实现呢?

可以考虑以右上角的节点为基准点,如果查找的元素比基准点小,那么基准点所在的列就可以排除了;如果查找的元素比基准点大,那么基准点所在的行就可以排除了,就这样反复排除,最后可以把时间复杂度降低到O(m+n),从左下角开始查找也是同样的道理,但是左上角和右下角就不行了,无法做到剔除某列或某行的效果;

基于这种思想;用Java做了如下的实现;

此题可以分为几种求法,可能是求是否能找到点,目标节点的坐标?所有目标节点的坐标?我实现了所有节点的坐标;

哇,写完了还挺多,想的比较多,矩阵还得判断各种合法性,反正多考虑一些总是对的嘛,我这简单就打印一下,具体可能会记日志神码的


package design;

import java.util.ArrayList;
import java.util.List; public class YoungTableau { private int row;
private int column;
private int value; public YoungTableau(int x, int y, int value) {
super();
this.setRow(x);
this.setColumn(y);
this.setValue(value);
} public YoungTableau() {
} /**
* @param args
*/
public static void main(String args[]) {
int matrix[][] = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 },
{ 6, 8, 11, 15 } };
/**
* 测试用例 1 input error matrix,column,row 2 test target>all elements or
* target<all elements 3 test target between elements
*/
printMatrix(matrix, 4, 4);
find(matrix, 4, 4, -3);
find(null, 4, 4, 88);
find(matrix, 0, 4, 5);
find(matrix, 4, -2, 5);
find(matrix, 4, 4, 5);
find(matrix, 4, 4, 7);
find(matrix, 4, 4, 1000);
find(matrix, 4, 4, -1);
} /**
* @param matrix
* @param rows
* @param columns
* @return 判断矩阵输入合法性
*/
private static boolean isValid(int[][] matrix, int rows, int columns) {
boolean isValid = false;
/** 判断二维矩阵每列合法性 */
if (matrix != null && rows > 0 && columns > 0) {
int rowLength = matrix.length;
if (columns <= rowLength) {
int columnLength = matrix[0].length;
for (int i = 1; i < rowLength; i++) {
columnLength = columnLength > matrix[i].length ? columnLength
: matrix[i].length;
if (columnLength > columns) {
return isValid;
}
}
isValid = true;
}
} else {
System.out.println("矩阵输入非法");
}
return isValid;
} /**
* @param result
*/
public static void printResult(List<YoungTableau> result) {
System.out.println("=====Begin=====");
if (result.size() == 0) {
System.out.println("There is no result");
}
for (YoungTableau yt : result) {
System.out.println("find value:" + yt.getValue() + " column:"
+ yt.getRow() + " column:" + yt.getColumn());
}
System.out.println("=====End=====");
} /**
* @param matrix
* @param rows
* @param columns
* @param target
* @return
*/
public static List<YoungTableau> find(int[][] matrix, int rows,
int columns, int target) {
List<YoungTableau> result = new ArrayList<YoungTableau>();
/** 判空及异常的判断 */
if (isValid(matrix, rows, columns)) {
/** 先以右上角的节点为开始 */
int row = 0;
int column = columns - 1;
/** 结束循环的条件 */
while (row < rows && column >= 0) {
if (target == matrix[row][column]) {
/** 节点找到,向result加入节点元素 */
result.add(new YoungTableau(row, column,
matrix[row][column]));
/** 如果找到,那么这行和这列都可以去掉 */
column--;
row++;
} else if (target < matrix[row][column]) {
/** 节点比基准点小,target所在列可以去除 */
column--;
} else {
/** 节点比基准点大,target所在行可以去除 */
row++;
} }
}
/** 这里为了方便直接打印一下 */
printResult(result);
return result;
} /**
* @param source
* @param rows
* @param columns
* 打印矩阵,调用的方法已经判空,此处省略
*/
public static void printMatrix(int[][] matrix, int rows, int columns) {
if (isValid(matrix, rows, columns)) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
System.out.print(matrix[i][j] + "\t");
}
System.out.println();
}
}
} public void setRow(int row) {
this.row = row;
} public int getRow() {
return row;
} public void setColumn(int column) {
this.column = column;
} public int getColumn() {
return column;
} public void setValue(int value) {
this.value = value;
} public int getValue() {
return value;
}
}

杨氏矩阵查找元素位置Java实现的更多相关文章

  1. 杨氏矩阵:查找x是否在矩阵中,第K大数

    参考:http://xudacheng06.blog.163.com/blog/static/4894143320127891610158/ 杨氏矩阵(Young Tableau)是一个很奇妙的数据结 ...

  2. (java)selenium webdriver学习--通过id、name定位,输入内容,搜索,关闭操作、通过tagname查找元素

    selenium webdriver学习--通过id.name定位,输入内容,搜索,关闭操作:通过tagname查找元素 打开谷歌浏览器,输入不同的网站,搜索框的定位含有不同元素(有时为id,有时为n ...

  3. 杨氏矩阵C++实现

    何为杨氏矩阵?这个网上的介绍很多,下面给出杨氏矩阵搜索算法: #include <iostream> using namespace std; // 杨氏矩阵查找算法 ], int N, ...

  4. Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置

    在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...

  5. 【Java实现】剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置)

    序数组中查找元素的起始位置):思路分享 <剑指offer>题目和LeetCode主站本质是一样的,想要找到target数目,也需要找到左右边界 题目解析: 在一个排序数组中,找到targe ...

  6. jsoup Java HTML解析器:使用选择器语法来查找元素

    jsoup Java HTML解析器:使用选择器语法来查找元素 使用选择器语法来查找元素 问题 你想使用类似于CSS或jQuery的语法来查找和操作元素. 方法 可以使用Element.select( ...

  7. 杨氏矩阵定义及其查找的实现C++

    先介绍一下这个数据结构的定义,Young Tableau有一个m*n的矩阵,然后有一数组 a[k], 其中 k<=m*n ,然后把a[k]中的数填入 m*n 的矩阵中,填充规则为: 1.  每一 ...

  8. 【C语言】二维数组中的查找,杨氏矩阵

    //二维数组中的查找,杨氏矩阵 //在一个二维数组中,每行都依照从左到右的递增的顺序排序.每列都依照从上到下递增的顺序排序. //请完毕一个函数.输入这种一个数组和一个数,推断数组中是否包括这个数. ...

  9. 类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。

      类 java.util.Collections 提供了对Set.List.Map进行排序.填充.查找元素的辅助方法. 1. void sort(List) //对List容器内的元素排序,排序的规 ...

随机推荐

  1. LSM树存储模型

    ----<大规模分布式存储系统:原理解析与架构实战>读书笔记 之前研究了Bitcask存储模型,今天来看看LSM存储模型,两者尽管同属于基于键值的日志型存储模型.可是Bitcask使用哈希 ...

  2. SHDocVw, AxSHDocVw的引用

    原文:SHDocVw, AxSHDocVw的引用 SHDocVw的引用SHDocVw一定要在下面这个路径找: 类似 C:\Program Files\Microsoft Visual Studio 9 ...

  3. 表现层及ASP.NET MVC介绍(一)

    表现层及ASP.NET MVC介绍(一) 本文将介绍表现层及ASP.NET MVC的一些要点,特别是ASP.NET MVC的一些抽象和封装技巧,如果你对MVC还不了解,可以参考<ASP.NET ...

  4. adb概览及协议参考

    原文:https://github.com/android/platform_system_core/blob/master/adb/OVERVIEW.TXT) Implementation note ...

  5. SQL 2005 中查询或执行另外的数据库操作的方法

    原文:SQL 2005 中查询或执行另外的数据库操作的方法 摘要: 如果,你想在一台数据库服务器上,查询另一个台数据服务器的数据该如何做呢?如果,你想在同一台数据服务器上,在不同的数据库之间查询数据, ...

  6. sql 中如何取出指定行: Row_Number

    原文:sql 中如何取出指定行: Row_Number ROW_NUMBER (Transact-SQL) USE AdventureWorks2008R2;GOWITH OrderedOrders ...

  7. bzoj 1799: [Ahoi2009]self 类似的分布 解读

    [原标题] 1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec  Memory Limit: 64 MB Submit: 554  Solved: 194 [id ...

  8. python进程池剖析(三)

    之前文章对python中进程池的原理.数据流以及应用从代码角度做了简单的剖析,现在让我们回头看看标准库中对进程池的实现都有哪些值得我们学习的地方.我们知道,进程池内部由多个线程互相协作,向客户端提供可 ...

  9. webapp 开发调试测试方法总结

    好久都没有发表过日志了,反正近期项目也已经接近尾声了,那么是时候该总结一下在项目中用到的技术了,请看:这里先废话几句,我们现在的开发模式是这样子的:先把本地的网页上传到远程服务器(因为好多设备都要去访 ...

  10. c#生成word文档

    参考:http://blog.163.com/zhouchunping_99/blog/static/7837998820085114394716/ 生成word文档 生成word文档 view pl ...