尝试答一个网络见到的面试题
题目:
@宝玉xp
最近我面试常问的一道题是“Remove Duplicates from an Array”,给个姓名字符串数组排重,基本上都能做出来,尤其是刷过题的,很快就能用HashMap或者Set给出最优解。
但接下来我会继续问:“如果把数组里面的项改成数字和字符串混合怎么办?”那么一些JS代码可能就不正确执行了。
接下来我又会问:“如果数组里的是一个User对象而不是字符串,怎么只根据id属性排重?”到这一步很多只会刷题的已经卡住了,完全无法根据之前HashMap的方案变通。
再接下来的问题会是:“如果要根据多个属性排重,比如id/name/age”,那么怎么办?这一步又要卡住一些人,又回到了原始的遍历查询,而不能坚持原本HashMap的方案。
前面的如果都通过了,最后还会问:“是否可以将这个方法变成一个通用的方法?即使不同的对象类型,不同的key组合,也可以共用”,如果有候选人能将获取key的方法作为参数,那应该可以得到一个比较高的评价。
这其实也是我面试时喜欢用的一种策略:
- 从简单的问题开始,让候选人可以轻松进入状态
- 逐步变更需求,考察候选人是不是在日常工作学习中对这些问题有过深入思考,能去解决一类问题而不是一个问题
- 尽可能贴近实际项目——比如上面的例子,如果写过Cache的get和set,其实不复杂
解答:
1,
public class WeiboExercise {
public static void main(String[] args) {
String[] array = new String[10];
array[0] = "Xiao Fei";
array[1] = "Zhang Wei";
array[2] = "Xiao Ming";
array[3] = "Li Si";
array[4] = "Wang Wu";
array[5] = "Zhang Wei";
array[6] = "Xiao Fei";
array[7] = "Xiao Ming";
array[8] = "Zhang San";
array[9] = "Mao Mao";
System.out.println(Arrays.toString(array));
String[] newArray = removeDuplicateStrings(array);
System.out.println(Arrays.toString(newArray));
}
public static String[] removeDuplicateStrings(String[] array) {
HashSet<String> set = new HashSet<String>();
for(String s : array) {
set.add(s);
}
String[] newArray = new String[set.size()];
int i = 0;
for(String s : set) {
newArray[i] = s;
i++;
}
return newArray;
}
}
2,
这个有点虚,不知道对不对。
public class WeiboExercise2 {
public static void main(String[] args) {
User[] array = new User[10];
array[0] = new User("100", "Xiao Fei");
array[1] = new User("90", "Zhang Wei");
array[2] = new User("10", "Xiao Ming");
array[3] = new User("110", "Li Si");
array[4] = new User("110", "Wang Wu");
array[5] = new User("130", "Zhang Wei");
array[6] = new User("10", "Xiao Fei");
array[7] = new User("50", "Xiao Ming");
array[8] = new User("30", "Zhang San");
array[9] = new User("200", "Mao Mao");
System.out.println(Arrays.toString(array));
User[] newArray = removeDuplicateStrings(array);
System.out.println(Arrays.toString(newArray));
}
public static User[] removeDuplicateStrings(User[] array) {
HashMap<String, User> map = new HashMap<String, User>();
for(User user : array) {
map.put(user.getId(), user);
}
User[] newArray = new User[map.size()];
int i = 0;
for(Map.Entry e : map.entrySet()) {
newArray[i] = (User)e.getValue();
i++;
}
return newArray;
}
}
class User {
private String id;
private String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return id + " " + name;
}
}
3,
答1:
这个就不写代码了,我想就把问题拆成,先根据id排重,然后把得到的新array作为参数,传到根据name排重的函数,再把结果传到根据age排重的函数。排重3次。我觉得肯定能运行,但算是个笨办法吧。
答2:
看了这个:https://www.geeksforgeeks.org/internal-working-of-hashmap-java/ 。我想到一个新办法,就是如果根据id/name/age去重的话,先根据id生成hashCode(),现在id一样的都在一个bucket里面,然后根据id/name/age重写equals()方法,如果三个都一样就return true。
这样3个都一样的情况下,就是碰撞的情况下,map.put()的时候,会判断equals(),如果equals()也return true,后面的User会replace掉前面的User,达到去重的目的。