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

比如

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. python tcp socket 多线程

    不多说,直接上代码 client.py #!/usr/bin/python import socket,sys,string host="localhost" port=8000 ...

  2. 随记一个C的毫秒级群PING

    正好公司为了检测前台网络,力图收集有力证据与某CDN PK,所以随手写了一个群PING的程序. 写的内容比较简单,没有去特别追求线程效率,也没有去用LINUX 2.6+的殿堂级神器,以追求实现效率为主 ...

  3. Quartz.NET 的任务调度管理工具

    [更新] 基于Quartz.NET 的任务调度管理工具   更新列表: 任务参数可视化. 立即中断正在执行的任务. 每个任务独立的应用程序域 上一版参见: 基于Quqrtz.NET 做的任务调度管理工 ...

  4. &lt;C++ 实现设计模式&gt; 观察者模式

    观察者模式,又称公布--订阅,mvc模式等. 通俗点讲,比方股票来说,非常多人关注一支股票,派一个人去观察股票的情况,一有变化(观察),就通知全部的预定这个消息的人. 而我们常见的mvc模式,v是指v ...

  5. IOS发展--他们控制的定义

    有没有这样的要求,,自定义panel,里面放几个控件,在多个页面中使用此panel. 有三个观点来解决这个问题: 1.自己继承UIView写一个类,在它是在代码的形式加入需要控制.完成布局. 2.使用 ...

  6. valid number 判断字符串是否为有效数字

    RT,面试题,给定一个字符串判断是否为科学计数法的有效数字.此题各种繁琐考虑.今天终于学会了用有限状态机来处理.理解之后简洁易懂.在此分享我的理解推导思路,大有收获啊. 网上有解法说先记录每个状态代表 ...

  7. sql datalength与len区别用法

    原文:sql datalength与len区别用法 len ( string_expression )参数:要计算的字符串 len() 函数len 函数返回文本字段中值的长度. sql len() 语 ...

  8. .9 png图片的制作

    在android开发的过程中我们经常因为没有好的美工图片失真,这样使界面看起来要逊色很多,有的时候可能我们会想在drawable-hdpi,ldpi,mdpi下放不同分辨率的图片,这样虽然可以有效避免 ...

  9. 无线连接手机进行Android测试

    当每天走到哪都要拿一根数据线进行项目测试的时候,总是有一些焦急和烦躁的,如果能够无线连接测试就在好不过了. 这样不再是什么难事了,只需要几步走: 在进行无线连接测试的过程中,你的手机必须root了,这 ...

  10. 推荐一个比较好的VBS编辑器

    QTP 本身的IDE环境, 有诸多缺陷.所以,一般中级以上的自动化测试工程师都会采用外部其他编辑器来编辑VBS脚本.通常情况下,一般都 notepad++. 但是,notepad++也是有很多不足之处 ...