2019校招真题编程练习 - 1 - 牛牛找工作

题目描述

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。

输入描述

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。

输出描述

对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。

示例

输入
3 3
1 100
10 1000
1000000000 1001
9 10 1000000000

输出
100
1000
1001

思路

在工作难度小于等于自身能力的工作中,选择其中最高的报酬。

解题思路

将工作难度与报酬输入一个二维数组jobs,将能力值与员工编号输入一个数组people。
在这里插入图片描述
将工作报酬按报酬从大到小排序,根据员工能力值与工作难度进行比较,因为报酬从大到小排序,所以按照当数组自增jobIdx遍历工作难度时,满足(工作难度<能力值)条件的第一个工作难度对应的报酬一定是最大的,此时拿到该员工编号与工作报酬的值,people++;否则增加jobIdx

import java.util.Scanner;
import java.util.Arrays;
import java.util.Comparator;

public class Main{
    public static void main(String[] args){
        Scanner s = new Scanner(System.in);
        int N = s.nextInt();
        int M = s.nextInt();
        if(N < 1 || M < 1)
            return;
        
        
        int[][] jobs = new int[N][2];
        int[][] people = new int[M][2];
        
        for(int i=0; i<N; i++){
            jobs[i][1] = s.nextInt();
            jobs[i][0] = s.nextInt();
        }
        //jobs逆序排序
        Arrays.sort(jobs, (int[] a1,int[] a2)->{
            if(a1[0]<a2[0])
                return 1;
            else if (a1[0]>a2[0])
                return -1;
            else 
                return 0;
        });
        
        for(int i=0; i<M; i++){
            people[i][0] = s.nextInt();
            people[i][1] = i;
        }
        //people逆序排序
        Arrays.sort(people, (int[] a1,int[] a2)->{
            if(a1[0]<a2[0])
                return 1;
            else if (a1[0]>a2[0])
                return -1;
            else 
                return 0;
        });
        

         int jobIdx = 0, peopleIdx = 0;
        int[] result = new int[M];
        
        while(peopleIdx < M && jobIdx < N){
            if(jobs[jobIdx][1] <= people[peopleIdx][0]){
                result[people[peopleIdx][1]] = jobs[jobIdx][0];
                peopleIdx++;
            }else
                jobIdx ++;
        }


        
        for (int i = 0; i < M; i++)
            System.out.println(result[i]);

    }
}

· Arrays.sort()

import java.util.Arrays;

Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用。

1)Arrays.sort(int[] a)

对一个数组的所有元素进行排序,并且是按从小到大的顺序。

import java.util.Arrays;

public class Main{
	public static void main(String[] args){
		int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
		Arrays.sort(a);
		for(int i=0; i<a.length; i++){
			System.out.print(a[i]+ " ");
		}
	}
}

运行结果:
0 1 2 3 4 5 6 7 8 9

2)Arrays.sort(int[] a, int fromIndex, int toIndex)

对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序. [fromIndex, toIndex)
注意:下标为toIndex的元素不参与排序哦!

import java.util.Arrays;

public class Main{
	public static void main(String[] args){
		int[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
		Arrays.sort(a, 0, 3);
		for(int i=0; i<a.length; i++){
			System.out.print(a[i]+ " ");
		}
	}
}

运行结果:
7 8 9 2 3 4 1 0 6 5

3) Arrays.sort(T[] array, int fromIndex, int toIndex, Comparator c)

可实现从大到小的排序。
注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char)
而要使用它们对应的类(Integer)

Comparator

在java中,如果要对集合对象或数组对象进行排序,需要实现Comparator接口以达到我们想要的目标。

import java.util.Arrays;
import java.util.Comparator;

public class Main{
	public static void main(String[] args){
		Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
		Comparator cmp = new MyComparator();
		Arrays.sort(a,cmp);
		for(int i=0; i< a.length; i++){
			System.out.print(a[i] + " ");
		}
 	}
}
class MyComparator implements Comparator<Integer>{
	@Override
	public int compare(Integer n1, Integer n2){
			//如果n1小于n2,我们就返回正值,如果n1大于n2我们就返回负值:从大到小排序
			//颠倒:从小到大
			if(n1<n2){
				return 1;
			}else if (n1>n2){
				return -1;
			}else
				return 0;
	}
}

String[] data = {"1", "4", "3", "2"};
System.out.println(Arrays.toString(data)); // [1, 4, 3, 2]
// 实现降序排序,返回-1放左边,1放右边,0保持不变
Arrays.sort(data, (str1, str2) -> {
    if (str1.compareTo(str2) > 0) {
		return -1;
    } else {
        return 1;
    }
});
System.out.println(Arrays.toString(data)); // [4, 3, 2, 1]

哈希表

数组:采用一段连续的存储单元来存储数据。对于指定下标的查找,时间复杂度为O(1);通过给定值进行查找,需要遍历数组,逐一比对给定关键字和数组元素,时间复杂度为O(n),当然,对于有序数组,则可采用二分查找,插值查找,斐波那契查找等方式,可将查找复杂度提高为O(logn);对于一般的插入删除操作,涉及到数组元素的移动,其平均复杂度也为O(n)

线性链表:对于链表的新增,删除等操作(在找到指定操作位置后),仅需处理结点间的引用即可,时间复杂度为O(1),而查找操作需要遍历链表逐一进行比对,复杂度为O(n)

二叉树:对一棵相对平衡的有序二叉树,对其进行插入,查找,删除等操作,平均复杂度均为O(logn)。

哈希表:相比上述几种数据结构,在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下(后面会探讨下哈希冲突的情况),仅需一次定位即可完成,时间复杂度为O(1),接下来我们就来看看哈希表是如何实现达到惊艳的常数阶O(1)的。

数据结构的物理存储结构只有两种:顺序存储结构链式存储结构(像栈,队列,树,图等是从逻辑结构去抽象的,映射到内存中,也这两种物理组织形式),而在上面我们提到过,在数组中根据下标查找某个元素,一次定位就可以达到,哈希表利用了这种特性,哈希表的主干就是数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值