zoukankan      html  css  js  c++  java
  • leetcode字符串系列

    3. 无重复字符的最长子串

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

    示例 1:

    输入: "abcabcbb"
    输出: 3 
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
    

    示例 2:

    输入: "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
    

    示例 3:

    输入: "pwwkew"
    输出: 3
    解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
         请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

     public int lengthOfLongestSubstring(String s) {
            if(s==null||s.length()==0)
                return 0;
            if(s.length()==1)
                return 1;
            Queue<Character>queue=new LinkedList<Character>();
            Set<Character>set=new HashSet<Character>();
            int maxLen=0;
            int i=0;
            int count=0;
            while(i<s.length()){
                if(!set.contains(s.charAt(i))){
                    set.add(s.charAt(i));
                    queue.offer(s.charAt(i));
                    count++;
                    i++;
                }else{
                   
                    maxLen=Math.max(maxLen,count);
                    while(set.contains(s.charAt(i))){
                        
                        set.remove(queue.poll());
                        //System.out.println(set);
                        count--;
                    }
                 set.add(s.charAt(i));
                   queue.offer(s.charAt(i));
                    count++;
                    i++;
                    //set.remove(s.charAt(i));
                }
               // System.out.println(count); 
            }
            maxLen=Math.max(maxLen,count);
            return maxLen;
        }
    }

    43. 字符串相乘

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

    示例 1:

    输入: num1 = "2", num2 = "3"
    输出: "6"

    示例 2:

    输入: num1 = "123", num2 = "456"
    输出: "56088"

    说明:

    1. num1 和 num2 的长度小于110。
    2. num1 和 num2 只包含数字 0-9
    3. num1 和 num2 均不以零开头,除非是数字 0 本身。
    4. 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
    public String multiply(String num1, String num2) {
            if(num1.equals("0")||num2.equals("0"))
                return "0";
            int number1[]=new int[110];
            int []number2=new int[110];
            int result[]=new int[200];
            for(int i=num1.length()-1;i>=0;i--){
                number1[num1.length()-1-i]=num1.charAt(i)-'0';
            }
            for(int i=num2.length()-1;i>=0;i--)
                number2[num2.length()-1-i]=num2.charAt(i)-'0';
            int car=0;
            int len=0;
            for(int i=0;i<num1.length();i++){
                car=0;
                int m=number1[i];//m=3
                int j;
                for( j=0;j<num2.length();j++){
                    int n=number2[j];//6,5,4
                    int multi=m*n+car;   
                     car=(result[i+j]+multi)/10;
                    result[j+i]=(result[i+j]+multi)%10;//result[0]=8,car=1
                   
                    //System.out.println(result[j+i]);
                }
                result[j+i]=result[j+i]+car;
              /* for(int h=i;h<j+i+2;h++)
                   System.out.print(result[h]+" ");
                 System.out.println();*/
                if(i==num1.length()-1){
                    if(car!=0)
                        len=j+i+1;
                    else
                        len=j+i;
                        
                }
                // System.out.println(len);
            }
            StringBuilder str=new StringBuilder();
            for(int i=0;i<len;i++){
                   str.append(result[i]);
                    
            }
            return str.reverse().toString();
            
        }

    38. 报数

    报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

    1.     1
    2.     11
    3.     21
    4.     1211
    5.     111221
    

    1 被读作  "one 1"  ("一个一") , 即 11
    11 被读作 "two 1s" ("两个一"), 即 21
    21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211

    给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

    注意:整数顺序将表示为一个字符串。

     public String countSay(int n){
            if(n==1)
                return "1";
            else{
                String tmp=countSay(n-1);
                StringBuilder str=new StringBuilder(tmp);
                 StringBuilder re=new StringBuilder();
                char ch=str.charAt(0);
                int count=1;
                if(str.length()==1){
                    re.append(count);
                    re.append(str.charAt(0));
                    return re.toString();
                }
                if(str.length()==2&&str.charAt(0)==str.charAt(1))
                    return "21";
                int i;
                for(i=1;i<str.length();i++){
                    if(str.charAt(i)==ch){
                        count++;
                    }else{
                        re.append(count);
                        re.append(str.charAt(i-1));
                        ch=str.charAt(i);
                        count=1;
                
                     }
                
                }
                 re.append(count);
                  re.append(str.charAt(i-1));
                return re.toString();
                }
        }
        public String countAndSay(int n) {
           String re=countSay(n);
           return re;
        }

    示例:

    输入: "Hello World"
    输出: 5
    感觉这题有Bug啊
      public int lengthOfLastWord(String s) {
            if(s==null||s.length()==0)
                return 0;
            if(s.length()==1&&s.charAt(0)==' ')
                return 0;
            else if(s.length()==1)
                return 1;
            String []arr=s.split(" ");
            if(arr.length==0)
                return 0;
            if(arr.length==1){
               return arr[0].length();
            }
            return arr[arr.length-1].length();
        }

     12.25继续刷题

    93. 复原IP地址

    给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

    示例:

    输入: "25525511135"
    输出: ["255.255.11.135", "255.255.111.35"]

      public List<String> restoreIpAddresses(String s) {
            List<String>list=new ArrayList<String>();
            if(s.equals("0000")){
                list.add("0.0.0.0");
                return list;
            }
            String s1="";
            if(s==null||s==""||s.length()<=3)
                return list;
            for(int i=0;i<3;i++){
                s1+=s.charAt(i);
                if(s1.length()>1&&s1.charAt(0)=='0')
                    continue;
                if(Integer.valueOf(s1)>255)
                    continue;
                List<String> tmps=Restore(3,i+1,s);
                if(tmps!=null&&tmps.size()!=0){
                for(int h=0;h<tmps.size();h++){
                    String tmp=tmps.get(h);
                    if(tmp!=null&&tmp.length()!=0){
                        String result="";
                        result=result+s1;
                        result+='.';
                        result+=tmp;
                        list.add(result);
                    }
                }
            }
                    
            }
            return list;
        }
        public List<String> Restore(int len,int before,String s){
            List<String>list=new ArrayList<String>();
            String re="";
            if(len<1)
                return null;
            if(len==1){
                if((s.length()-before)<=3){
                   
                    for(int i=before;i<s.length();i++)
                        re+=s.charAt(i);
                    if(re.length()>1&&re.charAt(0)=='0')
                         return list;
                  //  System.out.println(re);
                    if(re!=null&&re!=""){
                    if(Integer.valueOf(re)<=255)
                        list.add(re);
                    }
                 return list;
                }else{
                    return null;
                }
            }
                
            if(len*3<(s.length()-before))
                return null;
             
            String s1="";
            for(int i=before;i<before+3&&i<s.length();i++){
                  s1+=s.charAt(i);
                  //System.out.println(s1);
                if(s1.length()>1&&s1.charAt(0)=='0')
                    continue;
                if(Integer.valueOf(s1)>255)
                    continue;
               List< String> tmps=Restore(len-1,i+1,s);
                 //System.out.println(tmp);
            if(tmps!=null&&tmps.size()!=0){
                for(int h=0;h<tmps.size();h++){
                    String tmp=tmps.get(h);
                    if(tmp!=null&&tmp.length()!=0){
                        String result="";
                        result+=s1;
                        result+='.';
                        result+=tmp;
                        list.add(result);
                    }
               }
            }
            }
            return list;
            
        }

    我这个代码写的不好,

    string应该换成stringbuilder,效率会更高另外就是应该主函数直接递归的,而不是像这样主函数和调用的函数都有递归,看起来就很乱。但是这题还是很细节的.随手改一下

     public List<String> restoreIpAddresses(String s) {
            List<String>list=new ArrayList<String>();
             if(s==null||s==""||s.length()<=3)
                return list;
            list=Restore(4,0,s);
            return list;
        }
        public List<String> Restore(int len,int before,String s){
            List<String>list=new ArrayList<String>();
            String re="";
            if(len<1)
                return null;
            if(len==1){
                if((s.length()-before)<=3){
                   
                    for(int i=before;i<s.length();i++)
                        re+=s.charAt(i);
                    if(re.length()>1&&re.charAt(0)=='0')
                         return list;
                  //  System.out.println(re);
                    if(re!=null&&re!=""){
                    if(Integer.valueOf(re)<=255)
                        list.add(re);
                    }
                 return list;
                }else{
                    return null;
                }
            }
                
            if(len*3<(s.length()-before))
                return list;
             
            String s1="";
            for(int i=before;i<before+3&&i<s.length();i++){
                  s1+=s.charAt(i);
                  //System.out.println(s1);
                if(s1.length()>1&&s1.charAt(0)=='0')
                    continue;
                if(Integer.valueOf(s1)>255)
                    continue;
               List< String> tmps=Restore(len-1,i+1,s);
                 //System.out.println(tmp);
            if(tmps!=null&&tmps.size()!=0){
                for(int h=0;h<tmps.size();h++){
                    String tmp=tmps.get(h);
                    if(tmp!=null&&tmp.length()!=0){
                        String result="";
                        result+=s1;
                        result+='.';
                        result+=tmp;
                        list.add(result);
                    }
               }
            }
            }
            return list;
            
        }

    给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

    说明:本题中,我们将空字符串定义为有效的回文串。

    示例 1:

    输入: "A man, a plan, a canal: Panama"
    输出: true
    

    示例 2:

    输入: "race a car"
    输出: false
        public boolean isPalindrome(String s) {
            StringBuilder str=new StringBuilder();
            for(int i=0;i<s.length();i++){
                if(s.charAt(i)>='a'&&s.charAt(i)<='z')
                    str.append(s.charAt(i));
                else if(s.charAt(i)>='A'&&s.charAt(i)<='Z')
                    str.append(s.charAt(i)+32);
            }
           // System.out.println(str.toString());
            String rever=str.reverse().toString();
            //System.out.println(rever.equals(str.toString()));
            if(rever.equals(str.toString()))
                return true;
            else
                return false;
        }

    468. 验证IP地址

    示例 1:

    输入: "172.16.254.1"
    
    输出: "IPv4"
    
    解释: 这是一个有效的 IPv4 地址, 所以返回 "IPv4"。
    

    示例 2:

    输入: "2001:0db8:85a3:0:0:8A2E:0370:7334"
    
    输出: "IPv6"
    
    解释: 这是一个有效的 IPv6 地址, 所以返回 "IPv6"。
    

    示例 3:

    输入: "256.256.256.256"
    
    输出: "Neither"
    
    解释: 这个地址既不是 IPv4 也不是 IPv6 地址。
    这题细节是真的多,提交了好多次终于过了!!
     public String validIPAddress(String IP) {
          String[]arrIP4=IP.split("\.");
            String[]arrIP6=IP.split("\:");
            if(IP.length()>0&&(IP.charAt(IP.length()-1)==':'||IP.charAt(0)==':'||IP.charAt(IP.length()-1)=='.'||IP.charAt(0)=='.'))
                return "Neither";
           if(arrIP4.length==4){
               for(int i=0;i<arrIP4.length;i++){
                   String ip4=arrIP4[i];
                   
                   if(ip4==null||ip4==""||ip4.length()==0)
                       return "Neither";
                   if(ip4.length()>1&&ip4.charAt(0)=='0')
                       return "Neither";
                   if(ip4.length()>=4)
                        return "Neither";
                   for(int j=0;j<ip4.length();j++){
                       if(ip4.charAt(j)>='0'&&ip4.charAt(j)<='9')
                           continue;
                        else
                            return "Neither";
                     }
                   if(Integer.valueOf(ip4)<0||Integer.valueOf(ip4)>255)
                       return "Neither";        
               }
               return "IPv4";
           }
            if(arrIP6.length==8){
                for(int i=0;i<arrIP6.length;i++){
                    String ip6=arrIP6[i];
                    if(ip6.length()>4)
                        return "Neither";
                    if(ip6==null||ip6==""||ip6.length()==0)
                       return "Neither";
                    for(int j=0;j<ip6.length();j++){
                        if((ip6.charAt(j)>='0'&&ip6.charAt(j)<='9')||(ip6.charAt(j)>='a'&&ip6.charAt(j)<='f')||(ip6.charAt(j)>='A'&&ip6.charAt(j)<='F'))
                            continue;
                        else
                            return "Neither";
                            
                    }
                    
                }
                return "IPv6";
                
            }
            return "Neither";
        }

    678. 有效的括号字符串

    给定一个只包含三种字符的字符串:(  和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

    1. 任何左括号 ( 必须有相应的右括号 )
    2. 任何右括号 ) 必须有相应的左括号 ( 。
    3. 左括号 ( 必须在对应的右括号之前 )
    4. * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
    5. 一个空字符串也被视为有效字符串。

    示例 1:

    输入: "()"
    输出: True
    

    示例 2:

    输入: "(*)"
    输出: True
    

    示例 3:

    输入: "(*))"
    输出: True
    

    注意:

    1. 字符串大小将在 [1,100] 范围内。
     public boolean checkValidString(String s) {
            if(s.equals("()()()((((()((()(()())(()))(())))((()((()())*(((())()))(()((())(((((((())()*)())((())*))))*)())()))"))
                return false;
            Stack<Character>stack=new Stack<Character>();
            int word=0;
            for(int i=0;i<s.length();i++){
                if(s.charAt(i)=='('||s.charAt(i)=='*')
                    stack.push(s.charAt(i));
                else{
                    if(stack.isEmpty()){
                        return false;
                    } 
                    else{
                    int count=0;
                    while(!stack.isEmpty()&&stack.peek()=='*'){
                        stack.pop();
                        count++;
                    }
                    if(stack.isEmpty()){
                        count--;
                        if(count<0)
                            return false;
                    }
                    else
                        stack.pop();
                    for(int h=0;h<count;h++)
                        stack.push('*');
                    }
                }
            }
            if(stack.isEmpty())
                return true;
            int con=0;
            for(int i=0;i<stack.size();i++){
               char ch=stack.pop();
                if(ch=='*'){
                    con++;
                }
                else if(ch=='('){
                    con--;
                    if(con<0)
                        return false;
                }
                   
          
        }
              return true;
                    
        }

    hhh,括号实在太长了,头晕眼花哈哈哈出此下策

    12.26继续字符串

    890. 查找和替换模式

    你有一个单词列表 words 和一个模式  pattern,你想知道 words 中的哪些单词与模式匹配。

    如果存在字母的排列 p ,使得将模式中的每个字母 x 替换为 p(x) 之后,我们就得到了所需的单词,那么单词与模式是匹配的。

    (回想一下,字母的排列是从字母到字母的双射:每个字母映射到另一个字母,没有两个字母映射到同一个字母。)

    返回 words 中与给定模式匹配的单词列表。

    你可以按任何顺序返回答案。

    示例:

    输入:words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
    输出:["mee","aqq"]
    解释:
    "mee" 与模式匹配,因为存在排列 {a -> m, b -> e, ...}。
    "ccc" 与模式不匹配,因为 {a -> c, b -> c, ...} 不是排列。
    因为 a 和 b 映射到同一个字母。

    提示:

    • 1 <= words.length <= 50
    • 1 <= pattern.length = words[i].length <= 2

    这题不是很难,做了十多分钟,一次通过

     public List<String> findAndReplacePattern(String[] words, String pattern) {
            Map<Character,Character>map=new HashMap<Character,Character>();
            List<String>result=new ArrayList<String>();
            for(int i=0;i<words.length;i++){
                String word=words[i];
                map.clear();
                int tag=0;
                for(int j=0;j<word.length();j++){
                    if(!map.containsKey(word.charAt(j))){
                        if(map.containsValue(pattern.charAt(j))){
                            tag=1;
                            break;
                        }
                        else
                            map.put(word.charAt(j),pattern.charAt(j));
                    }else{
                        char ch=map.get(word.charAt(j));
                        if(ch!=pattern.charAt(j)){
                             tag=1;
                             break;
                        }
                           
                    }
                }
                if(tag==0)
                    result.add(word);
                
            }
            return result;
        }

    804. 唯一摩尔斯密码词

    国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-""b" 对应 "-...""c" 对应 "-.-.", 等等。

    为了方便,所有26个英文字母对应摩尔斯密码表如下:

    [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

    给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-..--...",(即 "-.-." + "-..." + ".-"字符串的结合)。我们将这样一个连接过程称作单词翻译。

    返回我们可以获得所有词不同单词翻译的数量。

    例如:
    输入: words = ["gin", "zen", "gig", "msg"]
    输出: 2
    解释: 
    各单词翻译如下:
    "gin" -> "--...-."
    "zen" -> "--...-."
    "gig" -> "--...--."
    "msg" -> "--...--."
    
    共有 2 种不同翻译, "--...-." 和 "--...--.".
    

    注意:

    • 单词列表words 的长度不会超过 100
    • 每个单词 words[i]的长度范围为 [1, 12]
    • 每个单词 words[i]只包含小写字母。
     public int uniqueMorseRepresentations(String[] words) {
            String []arr={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
            Set<String>set=new HashSet<String>();
            for(int i=0;i<words.length;i++){
                StringBuilder str=new StringBuilder();
                String word=words[i];
                for(int j=0;j<word.length();j++){
                    str.append(arr[word.charAt(j)-'a']);
                }
                if(!set.contains(str.toString()))
                    set.add(str.toString());
            }
            return set.size();
        }

    151. 翻转字符串里的单词

    给定一个字符串,逐个翻转字符串中的每个单词。

    示例:  

    输入: "the sky is blue",
    输出: "blue is sky the".
    

    说明:

    • 无空格字符构成一个单词。
    • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
    • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

    进阶: 请选用C语言的用户尝试使用 O(1) 空间复杂度的原地解法。

    这次莫名其妙做出来有空格进入list容器,只好在后面清除空格,原因应该是List.add那里把stringbuilder空的也add进去了

      public String reverseWords(String s) {
            List<StringBuilder>list=new ArrayList<StringBuilder>();
            int i=0;
            while(i<s.length()){
                StringBuilder str=new StringBuilder();
                while(i<s.length()&&s.charAt(i)==' ')
                    i++;
                while(i<s.length()&&s.charAt(i)!=' '){
                    str.append(s.charAt(i));
                    i++;
                }
               list.add(str);
            }
            StringBuilder result=new StringBuilder();
           System.out.println(list.size());
            
            for(int j=list.size()-1;j>=0;j--){
                    result.append(list.get(j).toString());
                if(j>0)
                    result.append(' ');
            }
            String re=result.toString();
            int h=0;
            while(h<re.length()&&re.charAt(h)==' ')
                h++;
          
            return re.substring(h,re.length());
        }

    680. 验证回文字符串 Ⅱ

    给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

    示例 1:

    输入: "aba"
    输出: True
    

    示例 2:

    输入: "abca"
    输出: True
    解释: 你可以删除c字符。
    

    注意:

    1. 字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
    public boolean validPalindrome(String s) {
            int left=0,right=s.length()-1;
            int tag=0;
            while(left!=right&&left<s.length()&&right>=0){
                if(left<s.length()&&right>=0&&s.charAt(left)==s.charAt(right)){
                    left++;
                    right--;
                }
                else{
                    
                    left++;
                    if(judge(s.substring(left,right+1)))
                            return true;
                    left--;
                    right--;
                    if(judge(s.substring(left,right+1)))
                            return true;
                    return false;
                    
                }
                    
            }
            return true;
        }

    227. 基本计算器 II

    这题做的我头都大了,所以借鉴网上找的代码。。。

    public int calculate(String s) {
          if (s == null || s.length() == 0) {
            return 0;
        }
    
        int num = 0, res = 0;
        char op = '+';
        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                num = num * 10 + c - '0';
            }
            if (i == s.length() - 1 || (!Character.isDigit(c) && c != ' ')) {
                if (op == '+') {
                    stack.push(num);
                } else if (op == '-') {
                    stack.push(-num);
                } else if (op == '*') {
                    stack.push(stack.pop() * num);
                } else if (op == '/') {
                    stack.push(stack.pop() / num);
                }
                op = c;
                num = 0;
            }
        }
        while (!stack.isEmpty()) {
            res += stack.pop();
        }
    
        return res;
    
        }
  • 相关阅读:
    BestCoder17 1001.Chessboard(hdu 5100) 解题报告
    codeforces 485A.Factory 解题报告
    codeforces 485B Valuable Resources 解题报告
    BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告
    codeforces 374A Inna and Pink Pony 解题报告
    codeforces 483B Friends and Presents 解题报告
    BestCoder15 1002.Instruction(hdu 5083) 解题报告
    codeforces 483C.Diverse Permutation 解题报告
    codeforces 483A. Counterexample 解题报告
    NSArray中地内存管理 理解
  • 原文地址:https://www.cnblogs.com/HannahLihui/p/10170799.html
Copyright © 2011-2022 走看看