首页 > 试题广场 >

矩阵元素查找

[编程题]矩阵元素查找
  • 热度指数:29131 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
已知一个有序矩阵mat,同时给定矩阵的大小nm以及需要查找的元素x,且矩阵的行和列都是从小到大有序的。设计查找算法返回所查找元素的二元数组,代表该元素的行号和列号(均从零开始)。保证元素互异。

数据范围:,矩阵中的任何元素满足
要求:空间复杂度 ,时间复杂度


示例1

输入

[[1,2,3],[4,5,6]],2,3,6

输出

[1,2]
示例2

输入

[[1,2,3]],1,3,2

输出

[0,1]
//时间复杂度O(n+logm)

import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        for (int i = 0; i < n; i++) {
            if (x >= mat[i][0] && x <= mat[i][m - 1]) {
                int l = 0;
                int r = m - 1;
                while (l <= r) {
                    int mid = (l + r) / 2;
                    if (mat[i][mid] > x) r = mid - 1;
                    else if (mat[i][mid] < x) l = mid + 1;
                    else return new int[]{i, mid};
                }
            }
        }
        return new int[]{-1, -1};
    }
}


发表于 2022-08-07 10:15:21 回复(0)
    public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
        for(int i=0;i<n;i++){
            if(mat[i][0]<=x && mat[i][m-1]>=x){
                int p1=0, p2=m-1;
                while(p1<=p2){
                    int mid=(p1+p2)/2;
                    if(mat[i][mid]==x){
                        return new int[]{i,mid};
                    }else if(mat[i][mid]>x){
                        p2=mid-1;
                    }else{
                        p1=mid+1;
                    }
                }
            }
        }
        return null;
    }

发表于 2022-07-17 14:56:59 回复(0)
3种解法
/**
 * NC86 矩阵元素查找
 */
public class NC86 {
	public int[] findElement(int[][] mat, int n, int m, int x) {
		// write code here
		int[] ans = new int[2];
		int i = n - 1;
		int j = 0;
		while (i >= 0 || j < m) {
			if (mat[i][j] == x) {
				ans[0] = i;
				ans[1] = j;
				return ans;
			} else if (mat[i][j] < x) {
				j++;
			} else {
				i--;
			}
		}
		return ans;
	}

	public int[] findElement0(int[][] mat, int n, int m, int x) {
		// write code here
		int[] ans = new int[2];
		for (int i = 0; i < n; i++) {
			int l = 0;
			int r = m - 1;
			while (l <= r) {
				int mi = l + ((r - l) >> 1);
				if (mat[i][mi] == x) {
					ans[0] = i;
					ans[1] = mi;
					return ans;
				} else if (mat[i][mi] < x) {
					l = mi + 1;
				} else {
					r = mi - 1;
				}
			}
		}
		return ans;
	}

	public int[] findElement1(int[][] mat, int n, int m, int x) {
		// write code here
		int[] ans = new int[2];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (mat[i][j] == x) {
					ans[0] = i;
					ans[1] = j;
					return ans;
				}
			}
		}
		return ans;
	}
}


发表于 2022-06-01 18:51:49 回复(0)
 public int[] findElement(int[][] mat, int n, int m, int x) {
        int col = m -1;
        int row = 0;
        while (col>=0 && row<=mat.length-1){
            if (mat[row][col]  == x){
                return  new int[]{row,col};
            }else if (mat[row][col] > x){
                col--;
            }else {
                row++;
            }
        }

        return null;
    }

发表于 2021-12-16 10:00:44 回复(0)
import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        // 有序数组
        if (m == 0 || n == 0) return null;
        int i = 0, j = 0;
                // 先确定 列的位置
        for ( ; j < m; ++ j) {
            if (mat[0][j] <= x && x <= mat[n - 1][j]) break;
        }
                // 再确定 行的位置
        for ( ; i < n; ++ i) {
            if (mat[i][j] == x) break;
        }
        int[] res = {i ,j};
        return res;
    }
}

发表于 2021-12-10 13:49:10 回复(0)
public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
        int[] res = new int[2];
        int i = 0;
        int j = m-1;
        //从上往下,从右往左比较,x>mat[i][j]则下移一行,x<mat[i][j]则左移一列
        while(i<n&&j>=0){
            if(mat[i][j]>x) j--;
            else if(mat[i][j]<x) i++;
            else{
                res[0]=i;
                res[1]=j;
                break;//一定要返回,否则会死循环
            }
        }
        return res;
    }

发表于 2021-09-03 16:22:15 回复(0)
public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        int[] res=new int[2];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(mat[i][j]==x){
                    res[0]=i;
                    res[1]=j;
                }
            }
        }
        return res;
        // write code here
    }
}
双循环不可以吗?可以通过所有用例~
发表于 2021-09-02 16:43:48 回复(0)
    public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
        /*
        从右上角开始,如果mat[i][j] < x,则下移动一行,如果mat[i][j] > x,则左移一行
        */
        int i = 0,j = m-1;
        while(i < n && i >= 0){
            if(mat[i][j] > x){
                j--;
            }else if(mat[i][j] < x){
                i++;
            }else{
                break;
            }
        }
        
        return new int[]{i,j};
    }
发表于 2021-08-22 21:16:05 回复(0)
* 思路: * 在矩阵中寻找元素,并返回该数的行和列。 * lin为行,row为列。 *      1、因为矩阵是有序的,所以我们首先可以拿该元素与每行最后一个元素比较 * 如果比最后一个元素大那肯定在下一行,lin++ *      2、在列中就相当于一元数组进行比较,得到该元素的列。
public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
        int lin; //行
        int row;//列
        int[] array = new int[2]; //设置结果一维数组。最终将行与列存入该数组。
        //遍历外层数组
        for (lin = 0; lin < n; lin++) {
            if(x > mat[lin][m-1]){
                continue;
            }else{
                //遍历该行的内部数组与m做比较得到列
                for (row = 0; row < m; row++) {
                    //比较大小
                    if(x == mat[lin][row]){
                        array[0] = lin;
                        array[1] = row;
                        break;
                    }
                }
            }
        }
        return array;
    }


发表于 2021-07-01 16:44:31 回复(0)
import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
        int i = 0;
        int j = m - 1;
        while (i < n && j >= 0) {
            if (mat[i][j] > x) {
                j--;
            } else if (mat[i][j] < x) {
                i++;
            } else {
                break;
            }
        }
        return new int[] {i, j};
    }
}
发表于 2021-05-29 16:15:27 回复(0)
import java.util.*;
public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        //为了个人的阅读方面,令m代表行,n代表列
        int tmp=n;
        n=m;m=tmp;
        int [] res=new int[2];
        //从右上角开始,如果x大于该数,则下移,若小于则右移
        int i=0,j=n-1;
        while(i<m&&j>=0)
            {
                if(x>mat[i][j])i++;
                else if(x<mat[i][j])j--;
                else{
                    res[0]=i;
                    res[1]=j;
                    break;
                }
            }
            return res;
    }
}

发表于 2021-04-15 20:25:02 回复(0)
public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
//         O(n^2)
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(mat[i][j]==x){
                    return new int[]{i,j};
                }
            }
        }
        return new int[]{-1,-1};
       
    }
发表于 2021-04-05 20:19:33 回复(0)
//二维数组中的查找
    public int[] findElement(int[][] mat, int n, int m, int x) {
        //初态在右上角位置 左至右升序 上至下升序 那么这个位置只能左走使得当前数减少和下走使当前数增加
        int row = 0, col = m-1;
        while (col>=0&&row<n){
            if (x>mat[row][col]) row++;//当前数小 要增加只能往下走
            else if (x<mat[row][col]) col--; //当前数太大 要减少只能左走
            else {//不大不小就是相等
                return new int[]{row,col};
            }
        }
        return new int[0];
    }

    //之所以一上来找行不行 是因为输入不是连续的 每一行跟下一行元素完全可以错开 不一定下面全比上面大
    //每一行进行一下二分即可
    public int[] findElement2(int[][] mat, int n, int m, int x) {
        int rowNum = 0, colNum = 0;
        for (int i = 0; i < n; i++) {
            colNum = binarySearch(mat, m, i, x);
            if (colNum != -1) {
                rowNum = i;
                return new int[]{rowNum, colNum};
            }
        }
        return new int[0];

    }

    public int binarySearch(int[][] mat, int m, int rowNum, int x) {
        int left = 0, right = m - 1, colNum = -1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (x == mat[rowNum][mid]) {
                colNum = mid;
                return colNum;
            } else if (x > mat[rowNum][mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }

编辑于 2021-03-16 17:26:45 回复(0)
import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        int[]goal=new int[2];
        int i=n-1,j=0;
        while(i>=0&&j<m){//从下往上,先确定行号,然后再遍历这一行确定列
            if(mat[i][j]==x){
                goal[0]=i;
                goal[1]=j;
                break;
            }
            else if(mat[i][j]>x) i--;
            else j++;//
        }
        return goal;
    }
}

发表于 2021-02-03 10:56:30 回复(0)
import java.util.*;
public class Solution {
    public static  int binaryarr(int[] arr,int begin,int end,int x){
        int mid=begin+(end-begin)/2;
        while(end>=begin){
            if(arr[mid]==x){
                return mid;
            }else if(arr[mid]>x){
                end=mid-1;
            }else{
                begin=mid+1;
            }
            mid=begin+(end-begin)/2;
        }
        return -1;
    }
    public static int[] findElement(int[][] mat, int n, int m, int x) {
        int begin=0;
        int end=m-1;
        int[] arr={0};
        int[] ret={0,0};
        for(int i=0;i<n;i++){
            if(x>=mat[i][0]&&mat[i][m-1]>=x){
                ret[0]=i;
                if((ret[1]=binaryarr(mat[i],begin,end,x))!=-1){
                    return ret;
                }
            }
        }
        return null;
    }
}
发表于 2020-12-10 19:55:45 回复(0)
解题思路:和右上角的值进行比较(或者左下角),目标值等于右上角直接返回二元数组,目标值小于右上角j--,目标值大于右上角i++;

public  int[] findElement(int[][] mat, int n, int m, int x) {
          //和右上角的值比较
          //定义行
          //定义列
          int i = 0;
          int j = m - 1;
          //int v = mat[i][j];
          while(i < n && j >= 0){
              if(x == mat[i][j]){
                  return new int[]{i,j};
                  //如果小于右上角的值j--;
              }else if(x < mat[i][j]){
                  j--;
                  //如果大于右上角的值i++;
              }else{
                  i++;
              }
          }
                    //找不到
          return new int[]{-1,-1};
      }

import java.util.*;
public class Solution{
    public int[] findElement(int[][] mat, int n, int m,int x){
        //和左下角数字比较
        //初始化行和列
        int i = n - 1;
        int j = 0;
        while(i >= 0 && j < m){
            //等于目标值
            if(x == mat[i][j]){
                return new int[]{i,j};
                        //大于目标值
            }else if(x < mat[i][j]){
                i--;
            //小于目标值    
            }else{
                j++;
            }
        }
                //找不到
        return new int[]{-1,-1};
    }
}


编辑于 2020-11-27 15:15:35 回复(0)
import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        // write code here
    	if (n < 1 || m < 1) {
    		return new int[0];
    	}
    	
    	int row_num = 0;
    	int column_num = m - 1;
    	int[] res = new int[2];
    	
    	while (row_num >= 0 && row_num < n && column_num >= 0 && column_num < m){
    		if (mat[row_num][column_num] == x) {
    			res[0] = row_num;
    			res[1] = column_num;
    			return res;
    		}
    		
    		if (mat[row_num][column_num] > x) {
    			column_num--;
    			continue;
    		}
    		
       		if (mat[row_num][column_num] < x) {
       			row_num++;;
    		}
    		
    	}
    	
    	return new int[0];
    }
}

发表于 2019-12-15 19:05:41 回复(0)
import java.util.*;

public class Solution {
    public int[] findElement(int[][] mat, int n, int m, int x) {
        int i=n-1;
        int j=0;
        int[] result=null;
        while(i>=0&&j<=m-1){
            if(x>mat[i][j]){
                j++;
            }else if(x<mat[i][j]){
               i--;
            }else{
                result=new int[2];
                result[0]=i;
                result[1]=j;
                return result;
            }
        }
        return null;
    }
}

发表于 2018-02-16 12:19:12 回复(0)