【剑指offer】【java】二维数组中的查找

题目

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

思路

直接从右上角或者左下角开始,如果是左下角,大于target i-- 小于target j++ 直到找到

代码

public class Solution {
    public boolean Find(int target, int [][] array) {
        int len = array.length;
        int width = array[0].length;
        int i = len-1;
        int j = 0;
        while(i>=0 && j<width){
            if(array[i][j]<target){
                j++;
            }else if(array[i][j]>target){
                i--;
            }else if(array[i][j]==target){
                return true;
            } 
        }
        return false;
    }
}

其他类似题型


1.数组操作

https://www.nowcoder.com/practice/325483e19dab4609baf00157e5ebeb6f
输入一个无序整数数组,调整数组中数字的顺序, 所有偶数位于数组的前半部分,使得所有奇数位于数组的后半部分。
要求时间复杂度为O(n)。
输入描述:
给定无序数组。
长度不超过1000000。
输出描述:
所有偶数位于数组的前半部分,所有奇数位于数组的后半部分。
如果有多个答案可以输出任意一个正确答案。
示例1
输入
复制
2 4 5 7 8 1
输出
复制
2 4 8 7 5 1

2.思路

定义两个指针,low high分别指向一前一后,如果前面的所指向的值是偶数 i++ 如果后面指向的是奇数 j-- 如果碰到两个前后都分别不是偶数或者奇数的时候,直接互换即可。

3.代码

import java.util.Scanner;
public class Main {
    public static void Solution(int[] array) {
        if(array==null||array.length==0) return;
        int low = 0;
        int high = array.length-1;
        while(low<high) {
            while(low<high&&(array[low]&1)==0) {
                low++;
            }
            while(low<high&&(array[high]&1)==1) {
                high--;
            }
            if(low<high) {
                int temp = array[low];
                array[low] = array[high];
                array[high] = temp;
            }
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String[] strArray = str.split(" ");
        int[] intArray = new int[strArray.length];
        for(int i = 0;i<strArray.length;i++) {
            intArray[i] = Integer.parseInt(strArray[i]);
        }
        Solution(intArray);
        for(int i = 0;i<intArray.length;i++) {
            System.out.print(intArray[i] + " ");
        }
    }
}

1.查找第k大元素

题目描述
给定一个无序的整型数组A[n],数组大小大于等于3,允许有值相同的元素;请设计算法找到该数组排序后第三大的元素值并输出.
输入描述:
一个非空的整数数组(至少有3个元素,可正可负)
输出描述:
第三大的元素值
示例1
输入
复制
[1,2,3,4,5]
输出
复制
3
示例2
输入
复制
[1,1,2,2,3]
输出
复制
2
示例3
输入
复制
[6,5,4,4,1,2]
输出
复制
4

2.思路

1.java中 Arrays.sort()方法–内置其实就是快排
2.堆排序

3.代码

import java.util.*;
public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String[] line = sc.nextLine().replace("[","").replace("]","").split(",");
        int[] arr = new int[line.length];
        for(int i = 0;i<line.length;i++){
            arr[i] = Integer.parseInt(line[i]);
        }
        Arrays.sort(arr);
        System.out.println(arr[arr.length -3]);
    }
}

4.总结:求无序数组的第k大或者第k小

链接:https://www.nowcoder.com/questionTerminal/673454422d1b4a168aed31e449d87c00
来源:牛客网

import java.util.PriorityQueue;
import java.util.Scanner;
import static java.lang.Integer.parseInt;
import static java.lang.System.in;
 
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(in);
        String[] str = sc.nextLine().replace("[", "").replace("]", "").split(",");
        int[] data = new int[str.length];
        for (int i = 0; i < data.length; i++) {
            data[i] = parseInt(str[i]);
        }
        System.out.println(findKthNum(data, 3));
        System.out.println(findKthNum1(data, 3));
    }
//方法1,基于快排思想的partion划分,时间复杂度O(n),空间复杂度O(1)
    public static int findKthNum(int[] data, int k) {
        int begin = 0, end = data.length - 1;
        int pos = 0;
        while (begin <= end) {
            pos = partion(data, begin, end);
            if (pos == k - 1) {
                return data[pos];
            } else if (pos > k - 1) {
                end = pos - 1;
            } else {
                begin = pos + 1;
            }
        }
        return -1;
    }
 
    private static int partion(int[] data, int begin, int end) {
        int temp = data[begin];
        while (begin < end) {
            while (begin < end && data[end] <= temp) {
                end--;
            }
            swap(data, begin, end);
            while (begin < end && data[begin] > temp) {
                begin++;
            }
            swap(data, begin, end);
        }
        return begin;
    }
 
    public static void swap(int[] arr, int i, int j) {
        if (arr == null || i >= arr.length || j >= arr.length || i < 0 || j < 0) {
            return;
        }
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    //方法2,建小顶堆,时间复杂度O(n*logk),空间复杂度O(k)
    public static int findKthNum1(int data[], int k) {
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        for (int item : data) {
            if (heap.size() < k) {
                heap.add(item);
            } else if (item > heap.peek()) {
                heap.poll();
                heap.add(item);
            }
        }
        return heap.poll();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值