leetcode: 451. Sort Characters By Frequency

451. Sort Characters By Frequency

Given a string, sort it in decreasing order based on the frequency of characters.

Input:
“tree”
Output:
“eert”
Explanation:
‘e’ appears twice while ‘r’ and ‘t’ both appear once.
So ‘e’ must appear before both ‘r’ and ‘t’. Therefore “eetr” is also a valid answer.


Input:
“cccaaa”
Output:
“cccaaa”
Explanation:
Both ‘c’ and ‘a’ appear three times, so “aaaccc” is also a valid answer.
Note that “cacaca” is incorrect, as the same characters must be together.


Input:
“Aabb”
Output:
“bbAa”
Explanation:
“bbaA” is also a valid answer, but “Aabb” is incorrect.
Note that ‘A’ and ‘a’ are treated as two different characters.


这道题目,开始想到的是用计数排序的思想,只是用hashmap代替数组的方式,排完序后对hashmap中的value按照逆序排序,最后根据value的大小打印value次数,从而实现。最后发现超时了,等会儿继续试试其他的方案。以下是超时的方案。

class Solution {
    public String frequencySort(String s) {
        char []ch = s.toCharArray();
        HashMap<Character,Integer> m = new HashMap();
        for(int i = 0; i<s.length(); i++)
            if(m.get(ch[i]) == null)
                m.put(ch[i],1);
            else
                m.put(ch[i],m.get(ch[i])+1);
        List<Map.Entry<Character, Integer>> list = new ArrayList<>(m.entrySet());
        String t = "";
        //降序排序
        Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
        for (Map.Entry<Character, Integer> mapping : list) {
            int x = mapping.getValue();
            while(x>0){
                t+=String.valueOf(mapping.getKey());
                x--;
            }
        }
        return t;
    }
}

在上一道问题还没有解决的情况下,又出现了一道新的查找表问题,也是超时!!!!问题如下 (median):

  1. 4Sum II
    Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.
    To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.

Example:

Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
Output:
2
Explanation:
The two tuples are:
(0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
(1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0


想法: O ( n 2 ) O(n^2) O(n2)的时间复杂度,对A,B两个数组进行求和并把结果存在HashMap中,键存A[i]+B[i]的结果,值存结果出现的频率,相当于一个freq[A[i]+B[i]]++,然后对C,D也是执行同样的过程,最后,对两个HashMap 中的键进行相加,如果为0,就对值进行相乘,得到组合数,最后加到结果中。
代码如下:

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        /**
        这道题的解题思路是,把A+B的和放在一个查找表中,C+D的和放入另一个查找表中,
        两个表的和相加等于0,记录数+1时间复杂度为O(N^2)
        **/
        HashMap<Integer,Integer> map1 = new HashMap();
        HashMap<Integer,Integer> map2 = new HashMap();
        for(int i = 0; i<A.length; i++)
            for(int j = 0; j<B.length; j++)
                if(map1.get(A[i]+B[j])==null)
                    map1.put(A[i]+B[j],1);
                else
                    map1.put(A[i]+B[j],map1.get(A[i]+B[j])+1);
        int res = 0;  //计数器
        for(int i = 0; i<C.length; i++)
            for(int j = 0; j<D.length; j++)
                if(map2.get(C[i]+D[j])==null)
                    map2.put(C[i]+D[j],1);
                else
                    map2.put(C[i]+D[j],map2.get(C[i]+D[j])+1);
        
        for(int key1:map1.keySet()){
            for(int key2:map2.keySet()){
                if(key1 + key2 == 0)
                    res+=map1.get(key1)*map2.get(key2);  //这里相乘是求得所有的组合
            }
        }
        return res;   
    }
}

很遗憾,还是超时了,这里是 3 ∗ O ( n 2 ) 3*O(n^2) 3O(n2)的时间复杂度,但还是有问题。下面是经过一轮的改进,这里的改进成了 2 ∗ O ( n 2 ) 2*O(n^2) 2O(n2),结果AC了:

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        /**
        这道题的解题思路是,把A+B的和放在一个查找表中,判断C,D之和的相反数是否在HashMap中,
        在的话就加上频率,时间复杂度为O(N^2)
        **/
        HashMap<Integer,Integer> map = new HashMap();
        for(int i = 0; i<A.length; i++)
            for(int j = 0; j<B.length; j++)
                if(map.get(A[i]+B[j])==null)
                    map.put(A[i]+B[j],1);
                else
                    map.put(A[i]+B[j],map.get(A[i]+B[j])+1);
        int res = 0;  //计数器
        for(int i = 0; i<C.length; i++)
            for(int j = 0; j<D.length; j++)
                if(map.get(0-C[i]-D[j])!=null)
                    res += map.get(0-C[i]-D[j]); 
        return res; 
    }
}
									等了好久,超时三连了!!!!

下面介绍一下这位让我超时的老兄:

49. Group Anagrams

Given an array of strings, group anagrams together.

Example:

Input: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Output:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

Note:

All inputs will be in lowercase.
The order of your output does not matter.

又虎又皮的我,直接上计数排序的那套,结果发现又是超时!!!!心态有点炸了

class Solution {
    class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String> >res = new ArrayList();
        for(int i = 0; i<strs.length; i++){
            if(strs[i] == null) // 剪枝
                continue;  
            List<String>L = new ArrayList();
            int []freq1 = new int[26];
            tofreq(strs[i],freq1);
            L.add(strs[i]);
            for(int k = i+1; k<strs.length;k++){
                if(strs[k] == null)   // 剪枝的时候别忘了这里,否则出bug
                    continue;
                int []freq2 = new int[26];
                tofreq(strs[k],freq2);
                if(issame(freq1,freq2)){
                    L.add(strs[k]);
                    strs[k] = null;   // 剪枝操作,下次到str[k]直接跳过
                }
            }
            res.add(L);
        }
        return res;
    }
    public boolean issame(int []a, int []b){
        for(int i = 0; i<26; i++)
            if(a[i] != b[i])
                return false;
        return true;
    }
    public void tofreq(String str, int []freq){
        char []x = str.toCharArray();
        for(int i=0; i<str.length(); i++)
            freq[x[i]-'a']++;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排序,可以使用双指针的方法来求解。假设数组从小到大排序,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值