二维数组中查找(多语言版)

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

Java
1. 暴力法

直接遍历二维数组,如果存在就返回true。时间复杂度O(n2)。

public class Main {

    //暴力法
    public boolean find(int target, int[][] array) {
        for (int[] arr : array) {
            for (int a : arr) {
                if (target == a) {
                    return true;
                }
            }
        }
        return false;
    }
}

测试结果:

运行时间:181ms 占用内存:17444k

2. 从左下角查找

由于序列具有以下性质:

  • 一行都按照从左到右递增的顺序排序
  • 每一列都按照从上到下递增的顺序排序

对左下角m来说,是该列最大值,是该行最小值

  1. 若m==target,返回true
  2. 若m>target,则row–
  3. 若m<target,则col++

时间复杂度为:O(rows+cols)

public class Main {

    //从左下角比较
    public boolean find(int target, int[][] array) {
        int rows = array.length;
        if (rows == 0) return false;
        int cols = array[0].length;
        int row = rows - 1;
        int col = 0;
        while (row >= 0 && col < cols) {
            if (array[row][col] > target) row--;
            else if (array[row][col] < target) col++;
            else return true;
        }
        return false;
    }
}

测试结果:

运行时间:165ms 占用内存:18488k

3.折半查找

从最后一行向上比较确定在那一行,对此行使用折半查找。对m行n列矩阵数组,时间复杂度为O(m+log2n)

public class Main {
    
    public boolean find(int target, int[][] array) {
        int rows = array.length;
        if (rows == 0) return false;
        int cols = array[0].length;
        if (cols == 0) return false;
        for (int row = rows - 1; row >= 0; row--) {
            if (target >= array[row][0] && target <= array[row][cols - 1]) {
                if (array[row][0] == target) return true;
                if (array[row][cols - 1] == target) return true;
                int left = 0, right = cols - 1;
                while (left < right) {
                    int mid = left + (right - left) / 2;
                    if (array[row][mid] == target) return true;
                    if (array[row][mid] > target) right = mid - 1;
                    if (array[row][mid] < target) left = mid + 1;
                }
                break;          //查找终止
            }
        }
        return false;
    }
}

测试结果:

运行时间:146ms 占用内存:18064k

Kotlin
fun find(target: Int, array: MutableList<MutableList<Int>>): Boolean {
    val rows = array.size
    if (rows == 0) return false
    val cols = array[0].size
    if (cols == 0) return false
    for (row in 0..<rows) {
        if (target >= array[row].first() && target <= array[row].last()) {
        	//二分查找
            if (target == array[row].first() || target == array[row].last()) return true
            var left = 0
            var right = cols - 1
            while (left <= right) {
                val mid = (right - left) / 2 + left
                array[row][mid].let {
                    if (it == target) return true
                    if (it > target) right = mid - 1
                    else left = mid + 1
                }
            }
            break
        }
    }
    return false
}
Python
def find(target: int, array: [[int]]) -> bool:
    rows = len(array)
    if rows == 0:
        return False
    cols = len(array[0])
    if cols == 0:
        return False
    for row in range(rows):
        if target >= array[row][0] or target <= array[row][-1]:
            if target == array[row][0] or target == array[row][-1]:
                return True
            left, right = 0, cols - 1
            while left <= right:
                mid = (right + left) // 2
                if array[row][mid] == target:
                    return True
                if array[row][mid] > target:
                    right = mid - 1
                else:
                    left = mid + 1
            break
    return False

Rust
fn find(target: i64, array: &Vec<Vec<i64>>) -> bool {
    let rows = array.len();
    if rows == 0 {
        return false;
    }
    let cols = array[0].len();
    if cols == 0 {
        return false;
    }

    for row in 0..rows {
        if target >= *array[row].first().unwrap() || target <= *array[row].last().unwrap() {
            if target == *array[row].first().unwrap() || target == *array[row].last().unwrap() {
                return true;
            }
            let mut left = 0;
            let mut right = cols - 1;
            while left <= right {
                let mid = (right - left) / 2 + left;
                if array[row][mid] == target {
                    return true;
                } else if array[row][mid] > target {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            break;
        }
    }
    false
}
Go
func find(target int, array [][]int) bool {
	rows := len(array)
	if rows == 0 {
		return false
	}
	cols := len(array[0])
	if cols == 0 {
		return false
	}

	for row := 0; row < rows; row++ {
		if target >= array[row][0] && target <= array[row][cols-1] {
			if target == array[row][0] || target == array[row][cols-1] {
				return true
			}
			left := 0
			right := cols - 1
			for left <= right {
				mid := (right-left)/2 + left
				if array[row][mid] == target {
					return true
				} else if array[row][mid] > target {
					right = mid - 1
				} else {
					left = mid + 1
				}
			}
			break
		}
	}
	return false
}
C++
#include <vector>

bool find(int target, std::vector<std::vector<int>>& array) {
    int rows = array.size();
    if (rows == 0) {
        return false;
    }
    int cols = array[0].size();
    if (cols == 0) {
        return false;
    }
    for (int row = 0; row < rows; row++) {
        if (target >= array[row][0] && target <= array[row][cols - 1]) {
            if (target == array[row][0] || target == array[row][cols - 1]) {
                return true;
            }
            // 二分查找
            int left = 0;
            int right = cols - 1;
            while (left <= right) {
                int mid = (right - left) / 2 + left;
                if (array[row][mid] == target) {
                    return true;
                } else if (array[row][mid] > target) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            break;
        }
    }
    return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值