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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值