Leetcode刷题 2021.01.08
Leetcode1138 字母板上的路径
我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。
在本题里,字母板为board = [“abcde”, “fghij”, “klmno”, “pqrst”, “uvwxy”, “z”],如下所示。
这道题还是比较简单,一开始以为是要做搜索回溯,后来想想都是固定的顺序,就直接找就完了,对于’z’要单独处理。就是代码写的又臭又长,不过也不想优化了,也没什么技巧,就当刷着玩吧。
class Solution {
public String alphabetBoardPath(String target) {
char[] arr = target.toCharArray();
char now = 'a';
StringBuilder sb = new StringBuilder();
for(int i = 0; i < arr.length; i++){
//先找初始坐标
int index1 = now - 'a', index2 = arr[i] - 'a';
int row1 = index1 / 5, row2 = index2 / 5;
int col1 = index1 % 5, col2 = index2 % 5;
//对于'z'要特殊处理一下
if (index1 == 25 || index2 == 25){
if (index1 == 25){
for(int k = 0; k < row1 - row2; k++) sb.append('U');
for(int k = 0; k < col2 - col1; k++)sb.append('R');
}else{
for(int k = 0; k < col1 - col2; k++) sb.append('L');
for(int k = 0; k < row2 - row1; k++)sb.append('D');
}
}else{
//其他25个数字
if (row1 > row2){
for(int k = 0; k < row1 - row2; k++) sb.append('U');
}else if (row2 > row1){
for(int k = 0; k < row2 - row1; k++) sb.append('D');
}
if (col1 > col2){
for(int k = 0; k < col1 - col2; k++) sb.append('L');
}else if (col2 > col1){
for(int k = 0; k < col2 - col1; k++) sb.append('R');
}
}
//找到了加感叹号
sb.append('!');
//改一下初始值
now = arr[i];
}
return sb.toString();
}
}
Leetcode1268 搜索推荐系统
给你一个产品数组 products 和一个字符串 searchWord ,products 数组中每个产品都是一个字符串。
请你设计一个推荐系统,在依次输入单词 searchWord 的每一个字母后,推荐 products 数组中前缀与 searchWord 相同的最多三个产品。如果前缀相同的可推荐产品超过三个,请按字典序返回最小的三个。
请你以二维列表的形式,返回在输入 searchWord 每个字母后相应的推荐产品的列表。
输入:products = [“mobile”,“mouse”,“moneypot”,“monitor”,“mousepad”], searchWord = “mouse”
输出:[
[“mobile”,“moneypot”,“monitor”],
[“mobile”,“moneypot”,“monitor”],
[“mouse”,“mousepad”],
[“mouse”,“mousepad”],
[“mouse”,“mousepad”]
]
一看题就知道是字典树,可能题刷多了,终于有点经验了。可是字典树很久没做过了,实现花了好久o(╯□╰)o。代码写的也有点乱,最后一提交发现才击败8%。不知道哪里有问题,就当做字典树模板记录下吧,周末有时间再优化下了。
class Solution {
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
//好像还是比较常规的字典树题
Tire t = new Tire();
List<List<String>> res = new ArrayList<>();
for(String product : products){
t.insert(product);
}
for(int i = 0; i < searchWord.length(); i++){
List<String> list = new ArrayList<>();
t.find(searchWord.substring(0, i + 1), list);
res.add(list);
}
return res;
}
class Tire{
class Node{
private boolean isEnd = false;
private Node[] next = new Node[26];
private String s;
public Node(){}
}
private Node root;
public Tire(){
root = new Node();
}
public void insert(String word) {
Node cur = root;
char[] arr = word.toCharArray();
for(int i = 0; i < arr.length; i++){
int temp = arr[i] - 'a';
if (cur.next[temp] == null){
cur.next[temp] = new Node();
}
cur = cur.next[temp];
}
cur.isEnd = true;
cur.s = word;
}
public void find(String word, List<String> list){
int count = 0;
Node cur = root;
char[] arr = word.toCharArray();
for(int i = 0; i < arr.length; i++){
int temp = arr[i] - 'a';
if (cur.next[temp] == null) return;
cur = cur.next[temp];
}
add(cur, list);
}
//递归找字典序最小的3个字符串
public void add(Node root, List<String> list){
if (list.size() == 3 || root == null) return;
if (root.isEnd == true) list.add(root.s);
for(int i = 0; i < 26; i++){
add(root.next[i], list);
}
}
}
}
Leetcode1338 数组大小减半
给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。
返回 至少 能删除数组中的一半整数的整数集合的最小大小。
输入:arr = [3,3,3,3,5,5,5,2,2,7]
输出:2
这题也不难,先用map统计每个数字的大小。再贪心地先删最大的就行了,好水啊。。
一到周五,就想着周末出去玩,没什么心情做题了。击败50%,也不高,周末有时间再优化吧。
可是周末还得憋论文,论文赶紧搞定就有大把时间学习了。
class Solution {
public int minSetSize(int[] arr) {
Map<Integer, Integer> map = new HashMap<>();
//用map统计
for(int ele : arr){
map.put(ele, map.getOrDefault(ele, 0) + 1);
}
List<Integer> list = new ArrayList<>();
for(Integer key : map.keySet()){
list.add(key);
}
//排序
Collections.sort(list, (x, y) -> (map.get(y) - map.get(x)));
int sum = 0, res = 0, i = 0;
while (sum < arr.length / 2){
sum += map.get(list.get(i));
res++;
i++;
}
return res;
}
}