Leecode-剑指Offer

1. 剑指Offer 03. 数组中重复的数字

找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
思路:

  • 利用桶排序的思想,在空间要求不严格的时候可以使用
  • 输入的每个数相当于桶的下标;循环遍历数组,将每个数字对应的桶数组中的值++;
  • 如果大于等于2,就返回桶下标
    题解:
class Solution {
public:
    int findRepeatNumber(vector& nums) {
        int size =nums.size();
        //temp为桶
        int temp[size];
        memset(temp,0,sizeof temp);
        int i;
        for(i=0;i<=size;i++)
        {
            temp[nums[i]]++;
            if(temp[nums[i]]>=2)
            {
                return nums[i];
            }
        }
        return 0;
    }
};

java:利用HashSet集合的性质,add的元素已存在时,返回false。

class Solution {
    public int findRepeatNumber(int[] nums) {
       HashSet hashSet = new HashSet();
        for (int i : nums) {
            if (!hashSet.add(i))
            {
                return i;
            }
        }
        return 0;
    }
}

复杂性分析
时间复杂度:O(n)O(n)O(n)。

遍历数组一遍。使用哈希集合(HashSet),添加元素的时间复杂度为 O(1)O(1)O(1),故总的时间复杂度是 O(n)O(n)O(n)。

空间复杂度:O(n)O(n)O(n)。不重复的每个元素都可能存入集合,因此占用 O(n)O(n)O(n) 额外空间。

链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-b-4/
来源:力扣(LeetCode)

2. 剑指 Offer 04. 二维数组中的查找

难度简单
描述:
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof

方法1:暴力搜索,直接二重循环查找
方法2:官方题解给出的方法,从右上角开始查询:row和column分别为二维数组的行和列,初始row为0,column为matrix[0].length-1;当前元素值大于target时,column--;小于时,row++;
跳出循环条件:row=0;
代码:

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        boolean res = false;
        //这里要判断一下x和y是否等于0
        int x = matrix.length;
        int y = matrix[0].length;
        int row = 0, column = y-1;
        int temp;

        while(row <= x-1 && column>=0)
        {
            temp = matrix[row][column];
            if(temp == target)
            {
                res = true;
                break;
            }
            if(temp > target)
            {
                column -= 1;
            }
            else
            {
                row += 1;
            }
        }
        return res;
    }
}

方法3:每一行做一次二分查找。截至条件跟上个方法类似,matrix[i][matrix[0].length-1](每行最右的元素)如果大于target就说明可能存在target;如果小于就可以不用查找当前行;如果matrix[i][0]大于target就说明不可能查到了。
(这个方法居然比官方给的题解快 )
代码:

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        boolean res = false;
        int x = matrix.length;
        if(x == 0)
            return false;
        int y = matrix[0].length;
        if(y == 0)
            return false;

        for (int[] ints : matrix) {
                    int high = y-1;
        int low = 0;
            if (ints[y - 1] < target)
                continue;
            else if (ints[0] > target)
                break;
            else {
                while (low <= high) {
                    if (ints[low] == target || ints[high] == target) {
                        res = true;
                        break;
                    }
                    if(high - low == 1)
                        break;
                    if (ints[(low + high) / 2] < target) {
                        low = (low + high) / 2 ;
                    } else
                        high = (low + high) / 2 ;

                }
            }

3. 美团笔试Q1:

  • 要求:买蛋糕,n为每天可以做出的蛋糕数目;m为已经做出的蛋糕数目;每个蛋糕有个整数重量。顾客要买蛋糕中最轻和最重的两个,且重量为a,b;蛋糕可以现做。
  • 输入输出:两行数据,第一行为四个数据:n, m, a, b。第二行为已经做好的蛋糕数量。问是否能满足顾客需求,能输出"YES",否则输出"NO"。
  • 例如输入:
    4 2 1 3
    2 2
    输出:YES
  • 代码:
import java.util.Arrays;
import java.util.Scanner;

public class Q1 {
    public static void main(String[] args) {
        int cake[]  = new int[1000];
        Scanner s = new Scanner(System.in);
        int n,m,a,b;
        while(true)
        {
            n=s.nextInt();
            m = s.nextInt();
            a = s.nextInt();
            b = s.nextInt();

            for(int i = 0; ib)
            {
                comp(cake, n, m, b, a);
            }
            else if(a= 1 && a <=cake[0])
                System.out.println("YES");
            else
                System.out.println("NO");
        }
        else if(a ==cake[0])
        {
            if(b == cake[m-1])
                System.out.println("YES");
            else if(n-m >= 1 && b >= cake[m-1])
                System.out.println("YES");
            else
                System.out.println("NO");
        }
        else if(b>=cake[m-1] && a<=cake[0] && n-m >=2)
        {
            System.out.println("YES");
        }
        else
            System.out.println("NO");
    }
}

4. 美团笔试Q2:计算晋级人数

  • 要求:给出n个人的分数,以排名第m个人的分数为界限,不低于此分数且得分不为0的晋级。要求输出晋级人数。
  • 输入输出:两行数据,第一行:人数n和m,第m个人的分数为晋级标准;第二行:n个人的分数
    例如输入:
    5 3
    4 2 0 0 0
    输出:
    2
  • 代码:
import java.util.Arrays;
import java.util.Scanner;

public class Q2{
    public static void main(String[] args) {
        int n,x;
        int sum = 0,max;
        Scanner s = new Scanner(System.in);
        n = s.nextInt();
        x = s.nextInt();
        int p[] = new int[n];
        for(int i = 0;i=0; i--)
        {
            if(p[i]>=max && p[i]!=0)
            {
                sum++;
            }
        }
        System.out.println(sum);
    }
}

5. 美团笔试Q3:循环数组求子数组最大和

你可能感兴趣的:(Leecode-剑指Offer)