20210723字符串类相关题目2(java)

  • Post author:
  • Post category:java





力扣第541题:反转字符串

这道题看着简单,但是自己写就遍历的时候出现了问题,想着先把长度分为2k等份或者k等份,但是都没成功,分完之后又需要写一个循环,重新reverse,哎这什么破想法,后来看了题解,题解的思路真是强大,循环i以2k自加,然后再找到需要反转的数组start和end,方法真好啊。

class Solution {
    public String reverseStr(String s, int k) {
        int n = s.length();
        if(k == 1) return s;

        char str[] = s.toCharArray();
        for(int start = 0;start<n;start+=2*k)
        {
            int i = start;//开始值
            int j = Math.min(i+k-1,n-1);//这里判断长度是否小于k
            while(i<j)
            {
                str[i] ^=str[j];
                str[j] ^=str[i];
                str[i] ^=str[j];
                i++;
                j--;
            }
        }
        return new String(str);

    }
}

其中代码随想录中给出了使用异或运算来进行交换,就是while里面的语句,这个也挺好的,我自己尝试了一下,发现可行,且没有额外空间产生。



力扣第557题:反转字符串中的单词

这道题想了想,先取出每个单词,用split划分,然后再遍历取反,再加个空格,最后返回就行。

class Solution {
    public String reverseWords(String s) {
        int n = s.length();
        String words[] = s.split(" ");

        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i<words.length;i++)
        {
            char ss[] = words[i].toCharArray();
            reverse(ss);
            sb.append(new String(ss));
            if(i<words.length-1) sb.append(" ");
        }
        return sb.toString();
    }

    public void reverse(char[] s)
    {
        int n = s.length;
        int i = 0;
        int j = n-1;
        while(i<j)
        {
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            i++;
            j--;
        }
    }
}

开始都准备看题解了,后来忍住自己做一做,还是做出来了。



力扣第151:翻转字符串里的单词

写了好长的代码,也算做出来了。

class Solution {
    public String reverseWords(String s) {
          if(s.length() == 0) return "";
        if(s.length() == 1) return s;

        String strs[] = s.split(" ");
   
		//去掉因为split剩下长度的空格
        List<String> tmp = new ArrayList<String>();
        for(String str:strs)
        {
            if(str.length() == 0|| str==null) continue;
            tmp.add(str);

        }
        String[] strs1 =tmp.toArray(new String[0]);
        
        
        int len = strs1.length;
        String copy[] = new String[len];
        StringBuilder sb=new StringBuilder();


		//进行反转
        for(int i = 0 ;i<len;i++)
        {
            copy[i] = strs1[len-i-1];
        }


		//增加空格
        for(int i = 0;i<len;i++)
        {
            sb.append(copy[i]);
            if(i<len-1) sb.append(" ");
        }
        return sb.toString();
    }
}
       

官方题解 几行搞定了:

class Solution {
    public String reverseWords(String s) {
        // 除去开头和末尾的空白字符
        s = s.trim();
        // 正则匹配连续的空白字符作为分隔符分割
        List<String> wordList = Arrays.asList(s.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}

这是我对string方法不熟造成的。

trim方法:返回一个新的字符串。这个字符串将删除了原始字符串头部和尾部的空格。

join方法:

String result = String.join(“-“,“a”,“b”,“c”,“d”);

输出结果如下:a-b-c-d



力扣第387题:字符串中的第一个唯一字符

这道题让我想到之前的类似重复的题,我使用hashmap完成的,发现时间复杂度比较大。

class Solution {
    public int firstUniqChar(String s) {
      int n = s.length();
      int ans =-1;

      int res = 0;

      Map<Character,Integer> map =new HashMap<>();
      for(int i = 0 ;i<n;i++)
      {

          if(map.containsKey(s.charAt(i)))
          {
             map.put(s.charAt(i),map.get(s.charAt(i))+1);
          }
          else
          {
              map.put(s.charAt(i),1);
          }
      }

      for(int i = 0 ;i<n;i++)
      {
          if(map.get(s.charAt(i))==1)
        {
            return i;
        }
          
      }
        return -1;
    }
}

看到评论区的几行代码,也用了下。

class Solution {
    public int firstUniqChar(String s) {
     int n = s.length();
     for(int i = 0 ;i<n;i++)
     {
         int first = s.indexOf(s.charAt(i));

         int nd = s.lastIndexOf(s.charAt(i));
         if(first == nd) return i;
     }
     return -1;
    }
}

这类题还是少用库函数,不过也得熟悉这些库函数方法是干嘛的就行,题解也是用的map来解得。



力扣389题:找不同

想着先排序,在做异或运算就行了。

class Solution {
    public char findTheDifference(String s, String t) {
        if(s==null||s.length()==0) return t.charAt(0);
        char ans = ' ';
        char chs[] = s.toCharArray();
        char cht[] = t.toCharArray();
        Arrays.sort(chs);
        Arrays.sort(cht);
        int i = 0;
        for(i = 0 ;i<s.length();i++)
        {
           if((chs[i]^cht[i])!=0)
           {
               ans = cht[i];
               break;
           }
           else
           {
               ans = cht[s.length()];
           }
        
        }
        return ans;
    }
}

异或运算 好快。

class Solution {
    public char findTheDifference(String s, String t) {
        if(s==null||s.length()==0) return t.charAt(0);
        char ans = ' ';
        char chs[] = s.toCharArray();
        char cht[] = t.toCharArray();
        int res = 0;
        for(char ch:chs)
        {
            res ^= ch;
        }

        for(char ch:cht)
        {
            res^=ch;
        }

        return (char) res;
    }
}



力扣第383题:赎金信

我借鉴了389题的思路:

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {

        int zzz[] = new int[26];
        for(int i = 0 ; i<magazine.length();i++)
        {
            zzz[magazine.charAt(i)-'a']++;
        }

        for(int i = 0 ;i<ransomNote.length();i++)
        {
            zzz[ransomNote.charAt(i)-'a']--;
            if(zzz[ransomNote.charAt(i)-'a']<0) return false;
        }
        return  true;
    }
}



力扣第242:有效的字母异词

和上一题一样的套路,真好;

class Solution {
    public boolean isAnagram(String s, String t) {
        int count[] = new int[26];
        if(s.length()!=t.length()) return false;
        for(int i = 0 ;i<s.length();i++)
        {
            char ch = s.charAt(i);
            count[ch-'a']++;
        }


        for(int i = 0 ;i<s.length();i++)
        {
            char ch = t.charAt(i);
            count[ch-'a']--;

            if(count[ch-'a']<0) return false;
        }
        return true;

    }
}

不过 ,时间却是3ms,我看看题解是怎么做的。题解是排序,看看是不是equals即可。



力扣第49题:字母异位词分组

这道题和之前异位词相似,但是呢,需要分组,这让我无从下手,不知道怎么分。

看了评论,才知道使用HashMap解决才快且好。便于理解,以后这样的分组需要知道这样,之前自己也做过,可能思想有点忘。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {

       Map<String,ArrayList<String>> map = new HashMap<>();
       for(String s:strs)
       {
           char ch[] = s.toCharArray();
           Arrays.sort(ch);
           String key = new String(ch);
           if(!map.containsKey(key)) map.put(key,new ArrayList<>());
           map.get(key).add(s);
       } 

       return new ArrayList(map.values());
    }
}



总结

今天先写到这里,不得不说,最近开始投简历了,让我有些紧张,比如京东面试需要问的手写ioc和aop,这些我都没有掌握,今晚再写一下吧,我还有好多知识要补习。



版权声明:本文为duan18291953965原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。