zoukankan      html  css  js  c++  java
  • 算法练习LeetCode初级算法之字符串

    • 反转字符串

    我的解法比较low,利用集合的工具类Collections.reverse反转,用时过长

    class Solution {

    public void reverseString(char[] s) {

    List<Character> list=new ArrayList<>();

    for (int i = 0; i < s.length; i++) {

    list.add(s[i]);

    }

    Collections.reverse(list);

    int i=0;

    for (Character character : list) {

    s[i++]=character;

    }

    }

    }

    简便方法:直接调换前后字符,感觉有点像数组算法,耗时也挺长

    class Solution {

    public void reverseString(char[] s) {

    for (int i = 0; i < s.length/2; i++) {

    char c=s[i];

    s[i]=s[s.length-i-1];

    s[s.length-i-1]=c;

    }

    }

    }

    操作字符串算法:耗时也挺长

    class Solution {

    public void reverseString(char[] s) {

    String string=new String(s);

    StringBuffer sBuffer=new StringBuffer(string);

    String string2=sBuffer.reverse().toString();

    for (int i = 0; i < s.length; i++) {

    s[i]=string2.charAt(i);

    }

    }

    }

    • 整数反转,检查是否越界

      每次都要检查一下,看是否越界,如果越界可能结果还是会输出,但却是错误结果 

      class Solution {

      public int reverse(int x) {

      int rev = 0;

      while (x != 0) {

      int pop = x % 10;

      x = x / 10;

      if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > 7))

      return 0;

      if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop < -8))

      return 0;

      rev = rev * 10 + pop;

      }

      return rev;

      }

      }

    • 字符串中的第一个唯一字符

    误区:在解这道题的时候,我脑子瓦特的掉进一个坑,用这个值与这个之后面的作比较,真是~~~蠢

    • 暴力法求解:直接把字符串转换为数组,然后分别于除了自身的其他数比较,如果相同,则相同数目加一

    然后,每次循环都要比较n是否=0,如果=0,说明没有与之相同的,得出结果,但运行时耗时太长,真心长

    class Solution {

    public int firstUniqChar(String s) {

    char[] cs = s.toCharArray();

    for (int i = 0; i < cs.length; i++) {

    int n=0;

    for (int j = 0; j < cs.length; j++) {

    if (i==j) {

    continue;

    }else if (cs[i]==cs[j]) {

    n++;

    }

    }

    if (n==0) {

    return i;

    }

    }

    return -1;

    }

    }

    • 操作字符串法:根据字符串的获取字符串的下标来比较,第一次出现的下标与最后一次出现的下标是否

    相等,如果相等则说明没有与其重复的字符,输出下标即可!耗时还说得过去。

    class Solution {

    public int firstUniqChar(String s) {

    char[] cs = s.toCharArray();

    for (int i = 0; i < cs.length; i++) {

    int index=s.indexOf(cs[i]);

    if (index==s.lastIndexOf(cs[i])) {

    return i;

    }

    }

    return -1;

    }

    }

    • 有效的字母词

      class Solution {

      public boolean isAnagram(String s, String t) {

          char[] cs1=s.toCharArray();

          char[] cs2=t.toCharArray();

          Arrays.sort(cs1);

          Arrays.sort(cs2);

          if (Arrays.equals(cs1, cs2)) {

                  return true;

              }

              return false;

       

      }

      }

    • 验证回文串

      解法摘要:把回文串都转换为小写,然后找出字母和数字,并放入一个动态数组,

      然后在进行比较。

      注意: 开头检查是否为空或特殊字符串,程序运行会快近一倍!!!

      class Solution {

      public boolean isPalindrome(String s) {

          if ("".equals(s)||s==null) {

                  return true;

              }

              s=s.toLowerCase();

              ArrayList<Character> list=new ArrayList<>();

              for (int i = 0; i < s.length(); i++) {

                  char c=s.charAt(i);

                  if (Character.isAlphabetic(c)||Character.isDigit(c)) {

                      list.add(c);

                  }

              }

              for (int i = 0; i < list.size()/2; i++) {

                  if (list.get(i)==list.get(list.size()-1-i)) {

                      continue;

                  }else {

                      return false;

                  }

              }

          return true;

      }

      }

    • 字符串转换整数(这题也太让人头秃了吧)

      请你来实现一个 atoi 函数,使其能将字符串转换成整数。

      首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

      当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

      该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

      注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

      在任何情况下,若函数不能进行有效的转换时,请返回 0

      说明:

      假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,qing返回  INT_MAX (231 − 1)  INT_MIN (−231)

      示例 1:

      输入: "42"

      输出: 42

      示例 2:

      输入: " -42"

      输出: -42

      解释: 第一个非空白字符为 '-', 它是一个负号。

        我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42

      示例 3:

      输入: "4193 with words"

      输出: 4193

      解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

      示例 4:

      输入: "words and 987"

      输出: 0

      解释: 第一个非空字符是 'w', 但它不是数字或正、负号。

      因此无法执行有效的转换。

      示例 5:

      输入: "-91283472332"

      输出: -2147483648

      解释: 数字 "-91283472332" 超过 32 位有符号整数范围。

        因此返回 INT_MIN (−231)

      逻辑比较简单,但是要考虑的方面太多!!!

    class Solution {

    public int myAtoi(String str) {

            str=str.trim();//去掉首尾空格

            if ("".equals(str)||str==null||str.equals("-")||str.equals("+")) {

                return 0;

            }

            char[] cs=str.toCharArray();

            StringBuffer s=new StringBuffer();

            boolean HaveNum=false;//判断是否有数字

            if (str.startsWith("-")) {

                s.append("-");

                for (int i = 1; i < cs.length; i++) {

                    if (Character.isDigit(cs[i])) {

                        s.append(cs[i]);

                        HaveNum=true;

                    }else {

                        break;

                    }

                }

            }else if (Character.isDigit(str.charAt(0))) {

                for (int i = 0; i < cs.length; i++) {

                    if (Character.isDigit(cs[i])) {

                        s.append(cs[i]);

                        HaveNum=true;

                    }else {

                        break;

                    }

                }

            }else if (str.startsWith("+")) {

                for (int i = 1; i < cs.length; i++) {

                    if (Character.isDigit(cs[i])) {

                        s.append(cs[i]);

                        HaveNum=true;

                    }else {

                        break;

                    }

                }

            }else {

                return 0;

            }

            str=s.toString();

            if (!HaveNum) {

                return 0;

            }

            BigInteger sum=new BigInteger(str, 10);

            if (sum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE))==1){

                return Integer.MAX_VALUE;

            }else if (sum.compareTo(BigInteger.valueOf(Integer.MIN_VALUE))==-1) {

                return Integer.MIN_VALUE;

            }else {

                return Integer.parseInt(s.toString());

            }

            

    }

    }

    • 实现strStr():利用KMP子字符串查找的思想

    要首先考虑为空和null的情况;

    class Solution {

    public int strStr(String haystack, String needle) {

        if (haystack==null||needle==null) {

                return -1;

            }

        if (needle.equals("")) {

                return 0;

            }

            int h=haystack.length();

            int n=needle.length();

            if (h==n) {

                if (haystack.equals(needle)) {

                    return 0;

                }

            }else {

                for (int i = 0; i <h-n+1; i++) {

                 int start=i;

                 int end=i+n;

                    String s=haystack.substring(start, end);

                    if (needle.equals(s)) {

                        return i;

                    }

                }

            }

        return -1;

     

    }

    }

    • 报数

    • 自己写这个程序犯了一个低级错误,导致浪费了大量时间,最后竟然利用这个越界错误抛出异常来实现,

    这个错误其实很好避免,只要是要两个指针操作即可!!!

    class Solution {

        public String countAndSay(int n) {

            StringBuffer s = new StringBuffer().append("1");

            if (n == 1) {

                return s.toString();

            }

            for (int j = 1; j < n; j++) {

                StringBuffer buffer = new StringBuffer();

                int[] count = new int[10];// 因为只会出现1-9,所以设置1-9数组计数器

                Arrays.fill(count, 0);

                List<Character> list = new ArrayList<>();

                int i = 0;

                while (i < s.length()) {

                    count[s.charAt(i) - '0']++;

                    list.add(s.charAt(i));

                    i++;

                }

                int k = 0;

                int jishu = 1;

                while (k < list.size()) {

                    char p = list.get(k);

     

                    try {

                        if (p != list.get(k + 1)) {

                            buffer.append(jishu);

                            buffer.append(p);

                            k++;

                            jishu = 1;

                        } else {

                            jishu++;

                            k++;

                        }

                    } catch (Exception e) {

                        buffer.append(jishu);

                        buffer.append(p);

                        s = buffer;

                        break;

                    }

     

                }

                s = buffer;

            }

            return s.toString();

        }

    }

    • 利用递归的思想同时用了双指针,如果相同,k直接跳过相同的,指向下一个数,然后如果不同,k—同时

      跳出内层for'循环,同时外面的k++,即从下一个不同的数开始!!!

    class Solution {

        public String countAndSay(int n) {

            String s = "1";

            if (n == 1) {

                return s;

            }

            for (int j = 1; j < n; j++) {

                s=SayNum(s);

            }

            return s.toString();

        }

        public String SayNum(String s) {

            StringBuffer buffer = new StringBuffer();

            for (int k = 0; k < s.length(); k++) {

                char p = s.charAt(k);

                int jishu = 0;

                for (int l = k; l < s.length(); l++) {

                    if (p==s.charAt(l)) {

                        jishu++;

                        k++;

                    }else {

                        k--;

                        break;

                    }

                }

                buffer.append(jishu).append(p);

            }

            return buffer.toString();

        }

    }

    • 最长公共前缀

    • 我的解法:真的是很暴力!!!有点麻烦!!从头到尾一个一个找

    class Solution {

    public String longestCommonPrefix(String[] strs) {

            StringBuffer buffer=new StringBuffer("");

            if (strs.length==0) {

                return "";

            }

            if (strs.length==1) {

                return strs[0];

            }

            String s=strs[0];

            for (int i = 0; i < s.length(); i++) {

                int z=0;

                try {

                    for (int j = 1; j < strs.length; j++) {

                        if (strs[j].charAt(i)==s.charAt(i)) {

                            z++;

                        }else {

                            continue;

                        }

                    }

                    if (z==strs.length-1) {

                        buffer.append(s.charAt(i));

                    }else {

                        break;

                    }

                } catch (Exception e) {

                    // TODO: handle exception

                    return buffer.toString();

                }

          

            }

        return buffer.toString();

    }

    }

    • 大神解法:简单直接,好理解,从整体开始,不一样就长度减一

    class Solution {

    public String longestCommonPrefix(String[] strs) {

        if (strs==null||strs.length==0) {

                return "";

            }

        String res=strs[0];

        for (int i = 1; i < strs.length; i++) {

                while (strs[i].indexOf(res)!=0) {

                    res=res.substring(0, res.length()-1);

                }

            }

        return res;

    }

    }

  • 相关阅读:
    日记功能发布
    功能小改进
    CuteEditor 6.0一个很奇怪的Bug
    关于博客园.NET俱乐部的公告
    新功能发布
    建立了一个博客园创业者QQ群
    思想决定生活 《卡耐基成功之道全书》读书笔记
    建立了一个英语学习小组
    实际上我没有选择的余地
    公告
  • 原文地址:https://www.cnblogs.com/GavinYGM/p/10324870.html
Copyright © 2011-2022 走看看