社招 美团一面
1、项目拷打
被质疑项目没啥难点和挑战。。。感觉没提炼好。。。
2、手撕代码
2.1、业务场景题
给你一个Product类,按下面的规则排序。
规则一:找到tag是“理发”,“按摩”,“染发”各自销量最高的一个商品排在最前,这三个商品之间又按照销量降序排列(tag是一个string类型)。
规则二:按是否商家推荐排序(boolean 类型 isRecommand)。
规则三:销量降序排序。
下面代码是通过AI优化之后的,当场写的比较烂
import java.util.*; import java.util.stream.Collectors; /** * 通用商品排序器,支持动态设置需要优先排序的标签 */ public class GenericProductSorter { // 优先排序的标签集合(从外部传入,可动态修改) private Set<String> priorityTags; // 每个优先标签下取销量最高的商品数量(此处按需求固定为1,也可改为动态参数) private int topNPerTag = 1; /** * 构造方法:传入需要优先排序的标签 * @param priorityTags 优先标签集合(如["理发", "按摩", "染发"]) */ public GenericProductSorter(Set<String> priorityTags) { this.priorityTags = new HashSet<>(priorityTags); // 防御性拷贝,避免外部修改影响内部 } /** * 动态修改优先标签 * @param newPriorityTags 新的优先标签集合 */ public void setPriorityTags(Set<String> newPriorityTags) { this.priorityTags = new HashSet<>(newPriorityTags); } /** * 获取排序比较器(核心方法) * @param allProducts 所有商品列表(用于预处理优先商品) * @return 符合规则的比较器 */ public Comparator<Product> getProductComparator(List<Product> allProducts) { // 预处理:根据当前的priorityTags,找出每个标签下销量最高的topNPerTag个商品 Set<String> topPriorityProducts = findTopPriorityProducts(allProducts); return (p1, p2) -> { // 判断商品是否属于优先商品 boolean p1IsTopPriority = topPriorityProducts.contains(p1.getId()); boolean p2IsTopPriority = topPriorityProducts.contains(p2.getId()); // 规则一:优先商品处理 if (p1IsTopPriority && p2IsTopPriority) { // 都是优先商品,按销量降序 return Integer.compare(p2.getSales(), p1.getSales()); } else if (p1IsTopPriority) { // 只有p1是优先商品,p1在前 return -1; } else if (p2IsTopPriority) { // 只有p2是优先商品,p2在前 return 1; } // 规则二:按是否推荐排序 if (p1.isRecommand() && !p2.isRecommand()) { return -1; } else if (!p1.isRecommand() && p2.isRecommand()) { return 1; } // 规则三:按销量降序 return Integer.compare(p2.getSales(), p1.getSales()); }; } /** * 找出每个优先标签下销量最高的topNPerTag个商品ID */ private Set<String> findTopPriorityProducts(List<Product> allProducts) { Set<String> topProductIds = new HashSet<>(); // 按当前的priorityTags分组处理 Map<String, List<Product>> productsByTag = allProducts.stream() .filter(p -> priorityTags.contains(p.getTag())) // 使用动态设置的优先标签 .collect(Collectors.groupingBy(Product::getTag)); // 每个标签取销量最高的topNPerTag个商品 for (List<Product> tagProducts : productsByTag.values()) { tagProducts.sort((p1, p2) -> Integer.compare(p2.getSales(), p1.getSales())); int limit = Math.min(topNPerTag, tagProducts.size()); for (int i = 0; i < limit; i++) { topProductIds.add(tagProducts.get(i).getId()); } } return topProductIds; } // 测试:动态修改优先标签的效果 public static void main(String[] args) { // 1. 初始化商品列表(同上) List<Product> products = Arrays.asList( new Product("1", "理发", true, 150), new Product("2", "按摩", false, 200), new Product("3", "染发", true, 180), new Product("4", "美甲", true, 300), new Product("5", "理发", false, 120), new Product("6", "美容", false, 90), new Product("7", "按摩", true, 250), new Product("8", "染发", false, 220), new Product("9", "理发", true, 300), new Product("10", "染发", true, 150), new Product("11", "理发", false, 200), new Product("12", "按摩", true, 180) ); // 2. 第一次排序:使用默认优先标签["理发", "按摩", "染发"] Set<String> defaultTags = new HashSet<>(Arrays.asList("理发", "按摩", "染发")); GenericProductSorter sorter = new GenericProductSorter(defaultTags); products.sort(sorter.getProductComparator(products)); System.out.println("=== 优先标签:理发、按摩、染发 ==="); printProducts(products); // 3. 第二次排序:动态修改优先标签为["美甲", "美容"] Set<String> newTags = new HashSet<>(Arrays.asList("美甲", "美容")); sorter.setPriorityTags(newTags); // 修改优先标签 products.sort(sorter.getProductComparator(products)); System.out.println("\n=== 优先标签:美甲、美容 ==="); printProducts(products); } // 辅助方法:打印商品列表 private static void printProducts(List<Product> products) { for (Product p : products) { System.out.printf("%s (标签: %s, 销量: %d, 推荐: %s) %n", p.getName(), p.getTag(), p.getSales(), p.isRecommand()); } } } // Product类保持不变 class Product { private String id; private String name; private String tag; private boolean isRecommand; private int sales; public Product(String id, String tag, boolean isRecommand, int sales) { this.id = id; this.name = "商品" + id; this.tag = tag; this.isRecommand = isRecommand; this.sales = sales; } // getter方法 public String getId() { return id; } public String getName() { return name; } public String getTag() { return tag; } public boolean isRecommand() { return isRecommand; } public int getSales() { return sales; } }
2.2、算法题
滑动窗口,hard中比较简单的吧,当场给了思路,口胡了一下,但是面试官急着去面试下一个人没打完,今天补题过了。
class Solution { public String minWindow(String S, String T) { char[] t = T.toCharArray(); char[] s = S.toCharArray(); Map<Character, Integer> tar = new HashMap<>();// 记录t字符出现的情况 for (char c : t) { tar.put(c, tar.getOrDefault(c, 0) + 1); } int l = 0, r = 1; String ans = S + T; Map<Character, Integer> cur = new HashMap<>(); // 滑动窗口中字符出现的情况 cur.put(s[0], cur.getOrDefault(s[0], 0) + 1); while (r < s.length && l < r) { if (check(cur, tar)) { if (r - l < ans.length()) { ans = S.substring(l, r); } cur.put(s[l], cur.get(s[l]) - 1); ++l; } else { cur.put(s[r], cur.getOrDefault(s[r], 0) + 1); ++r; } } while (check(cur, tar) && l < r) { if (r - l < ans.length()) { ans = S.substring(l, r); } cur.put(s[l], cur.get(s[l]) - 1); ++l; } if (ans.length() > s.length) { ans = ""; } return ans; } private boolean check(Map<Character, Integer> cur, Map<Character, Integer> tar) { for (Map.Entry<Character, Integer> entry : tar.entrySet()) { if (entry.getValue() > cur.getOrDefault(entry.getKey(), 0)) { return false; } } return true; } public static void main(String[] args) { String s = "ADOBECODEBANC", t = "ABC"; Solution solution = new Solution(); solution.minWindow(s, t); } }#美团##社招#