【Leetcode】String

来源:互联网 发布:mysql数据库 pdf 编辑:程序博客网 时间:2024/06/05 07:40

注:Java中 String常用函数:

String str:str.length()   //得到字符串长度str.charAt(i)  //得到指定位置字符str.charAt(i)-'0'  //将某个字符转换为int型char[] cs = str.toCharArray();  //将字符串转换为数组

一,转换题型

String to Integer (atoi)

【题目】Implement atoi to convert a string to an integer.

要求可以总结如下:
1. 字串为空或者全是空格,返回0;
2. 字串的前缀空格需要忽略掉;
3. 忽略掉前缀空格后,遇到的第一个字符,如果是‘+’或‘-’号,继续往后读;如果是数字,则开始处理数字;如果不是前面的2种,返回0;
4. 处理数字的过程中,如果之后的字符非数字,就停止转换,返回当前值;
5. 在上述处理过程中,如果转换出的值超出了int型的范围,就返回int的最大值或最小值。

public class Solution { public int myAtoi(String str) {  if (str.length() == 0)  return 0;   //空字串返回0   int i = 0;    while (str.charAt(i) != '\0' && str.charAt(i) == ' ')    ++i;    //忽略前缀空格   if (str.charAt(i) == '\0') //全为空格返回0     return 0;    //处理+、-号   int signal = 1;    if (str.charAt(i) == '+'){        signal = 1;        ++i;    }    else if (str.charAt(i) == '-'){        signal = -1;        ++i;    }    //转换整数    int sum = 0; int count = 0;  while ( i < str.length()) {     if (str.charAt(i) >= '0' && str.charAt(i) <= '9')       sum = sum * 10 + signal * (str.charAt(i)-'0');// 字符-'0'转换为int型!      else             return sum;        ++i;       ++count;   //溢出处理 Integer.MAX_VALUE:2147483647 ;Integer.MIN_VALUE:-2147483648   if(count>10) {  //字符串过长越界       if(signal == 1) return Integer.MAX_VALUE;       else if(signal == -1) return Integer.MIN_VALUE;    }   if (sum >= Integer.MAX_VALUE/10 && str.charAt(str.length()-1)-'0'>7 && count==9)    return  Integer.MAX_VALUE;  //位数与界限相同但越界   else if( sum<= Integer.MIN_VALUE/10  && str.charAt(str.length()-1)-'0'>8 && count==9)      return Integer.MIN_VALUE;    }    return sum;  }}

Roman to Integer

【题目】
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.

  解题思路:我们首先来明确一下罗马数字与阿拉伯数字的换算规则:如果当前数字比前一个大,说明这一段的值应该是当前这个值减去上一个值,比如IV = 5 – 1;否则,将当前值加入到结果中,然后开始下一段记录,比如VI = 5 + 1, II=1+1。而罗马数字与阿拉伯数字对应变换是:I对应1,V对应5,X对应10,L对应50,C对应100,D对应500,M对应1000。因此,只需要从前往后读出字符,如果当前数字小于等于前一字符,则加上前一字符对应的数字;而当前数字更大时,减去前一个字符。

public class Solution {  public int romanToInt(String s) {        int nums[]=new int[s.length()];        for(int i=0;i<s.length();i++){            switch (s.charAt(i)){                case 'M':                    nums[i]=1000;                    break;                case 'D':                    nums[i]=500;                    break;                case 'C':                    nums[i]=100;                    break;                case 'L':                    nums[i]=50;                    break;                case 'X' :                    nums[i]=10;                    break;                case 'V':                    nums[i]=5;                    break;                case 'I':                    nums[i]=1;                    break;            }        }        int sum=0;        for(int i=0;i<nums.length-1;i++){            if(nums[i]<nums[i+1])                sum-=nums[i];            else                sum+=nums[i];        }        return sum+nums[nums.length-1];   } }

Integer to Roman

【题目】
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.

public class Solution {    public String intToRoman(int number) {        int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };          String[] numerals = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };          StringBuilder result = new StringBuilder();          for (int i = 0; i < values.length; i++) {              while (number >= values[i]) {                  number -= values[i];                  result.append(numerals[i]);              }          }          return result.toString();      }}

二,Parentheses问题(Stack,DFS递归)

Valid Parentheses

【题目】
Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.

The brackets must close in the correct order, “()” and “(()[]{})” are all valid but “(]” and “([)]” are not.

【思路】利用一个栈来保存前括号,然后有后括号来时弹出栈顶来判断

public class Solution {    public boolean isValid(String s) {        char[] cs = s.toCharArray();        if (cs.length % 2 != 0) return false;        Stack<Character> stack = new Stack<Character>();        for(int i=0;i<cs.length;i++){            if(cs[i]=='[' || cs[i] == '(' || cs[i] == '{'){                stack.push(cs[i]);            }else{                if(stack.isEmpty()) return false;                switch (stack.pop()){                case '(':                    if(cs[i]!=')') return false;                    break;                case '[':                    if(cs[i]!=']') return false;                    break;                case '{':                    if(cs[i]!='}') return false;                    break;                }            }        }        if(!stack.isEmpty()) return false;        return true;     }}

Generate Parentheses

【题目】
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
“((()))”, “(()())”, “(())()”, “()(())”, “()()()”

【思路】
  这道题跟unique binary tree ii是类似的。如果是只求个数的话是类似unique binary tree,用到了卡特兰数。这里也是用到了类似的模型。
  不过这道题按照DFS那种递归想法解决还是比较容易想到的。给定的n为括号对,所以就是有n个左括号和n个右括号的组合。按顺序尝试知道左右括号都尝试完了就可以算作一个解。
  那么我们在什么情况下添加左括号呢?很明显,最多能添加n个左括号,在递归调用的时候,在能传递到最底层的共用字符串中先添加”(“,然后left-1,递归调用就可以。
  那什么时候添加右括号呢?当左括号个数大于右括号的个数时添加右括号(即剩余的左括号少于右括号时)。
  
这里写图片描述

代码如下:

public class Solution {    public List<String> generateParenthesis(int n) {        ArrayList<String> m=new ArrayList<>();        generate(m, "", n, n);        return m;    }    public void generate(ArrayList m, String s, int l, int r){        if(l==0 && r==0){             m.add(s);            return ;        }        if(l>0) generate(m, s+"(",  l-1,  r);        if(r>l) generate(m, s+")",  l,  r-1);    }}

三,Two Pointer

Implement strstr()

【题目】Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
  实现strstr(). 返回needle(关键字)在haystack(字符串)中第一次出现的位置,如果needle不在haystack中,则返回-1。
  注:strstr()是c++中的一个函数

  这是算法中比较经典的问题,判断一个字符串是否是另一个字符串的子串。这个题目最经典的算法应该是KMP算法。
  下面不是KMP算法,但是代码特别简洁:

public class Solution {    public int strStr(String haystack, String needle) {         int i, j;         for (i = j = 0; i < haystack.length() && j < needle.length();) {             if (haystack.charAt(i) == needle.charAt(j)) {                  ++i; ++j;             } else {                 i -= j - 1; j = 0;             }         }         return j != needle.length() ? -1 : i - j;    }}

四,Math

Pow(x, n)

Analysis:

If we just use the normal way of calculation, when face 1 to the power of 10000, the computation complexity is too high.

Consider this way:
If we want to get 2^10,

2^10 = 2^4 * 2^4 *2^2
2^4 = 2^2*2^2
2^2 = 2*2

Let’s see this in a bottom-up way, totally it needs to loop n/2 > 0 times, first we have 2^1=2, then we can have 2^2 = 2*2=4, and again we have 2^4 = 4*4, (key point:) and if n%2==1, we need one more previous value, which is 2^2 here, so we have 2^4*2^4*2^2 = 2^10.

We use binary divide method.

递归;二分法:

public class Solution {    public double myPow(double x, int n) {         if(n<0){              return 1.0/Power(x, -n);          }else {              return Power(x, n);          }      }      public double Power(double x, int n){          if(n==0)              return 1;          double v = Power(x, n/2);          if(n%2==0)              return v*v;          else              return v*v*x;      }}

Sqrt(x)

Implement int sqrt(int x).

二分搜索:

public class Solution {    public int mySqrt(int x) {        int begin=1;        int end=x;        while(begin<=end){         int mid=(begin+end)/2;           if(mid==x/mid) return mid; //不要写成mid*mid==x,会溢出           else if(mid<x/mid) begin=mid+1;         else end=mid-1;        }        return end; ////结束条件end<begin,所以返回end     }}

Valid Number

Validate if a given string is numeric.

Some examples:
“0” => true
” 0.1 ” => true
“abc” => false
“1 a” => false
“2e10” => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

注意事项:
  1. 前后空格
  2. “+”,”-“号
  3. “e”和”E”的出现位置
  4.”.”小数点的出现位置
  5. “1.”, “.34”,”+.1”也被认为是正确的

  1. https://gist.github.com/zrqsmcx/7098713 没有用状态转移表的有限状态机解法。

  2. http://www.cnblogs.com/chasuner/p/validNumber.html 带状态转移表的有限状态机解法,很简练。里面有对状态机个状态及合法输入的说明讲解。

  3. http://blog.csdn.net/fightforyourdream/article/details/12900751 给出了一种取巧的正则表达式匹配方法,同时也写了一个暴力解法(就是各种判断的解法)。且有很多其他链接。

  4. http://www.wangqifox.cn/wordpress/?p=437 比较简练的普通方法,搞懂这个也很不错。

  5. http://tech.ddvip.com/2014-04/1397886139209922.html 对2中一些解释的补充。

正则表达式匹配方法:

public class S65 {    public static void main(String[] args) {    }    public boolean isNumber(String s) {        if(s.trim().isEmpty()){            return false;        }        String regex = "[-+]?(\\d+\\.?|\\.\\d+)\\d*(e[-+]?\\d+)?";        if(s.trim().matches(regex)){            return true;        }else{            return false;        }    }}

Add Binary

Given two binary strings, return their sum (also a binary string).

For example,
a = “11”
b = “1”
Return “100”.

public class Solution {    public String addBinary(String a, String b) {        while(a.length()<b.length()){            String t=a;            a=b;            b=t;        }         int carr=0;        String res="";        String res2="";        int i=b.length()-1;        int j=a.length()-1;        while(i>=0){           int tmp=(a.charAt(j)-'0')+(b.charAt(i)-'0')+carr;//字符-'0'转换为int型!!!           res=res+tmp%2;           carr=tmp/2;           i--;           j--;       }        while(j>=0){            int s=(a.charAt(j)-'0')+carr;            res=res+s%2;            carr=s/2;            j--;        }        //倒序        for(int k=res.length()-1;k>-1;k--)        {            res2+=String.valueOf(res.charAt(k));        }        return (carr==1)?"1"+res2:res2;    }}

五,HashMap

Group Anagrams

题目:
Given an array of strings, group anagrams together.
For example, given: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Return:

[  ["ate", "eat","tea"],  ["nat","tan"],  ["bat"]]

思路:
判断两个词是否是变形词,最简单的方法是将两个词按字母排序,看结果是否相同。这题中我们要将所有同为一个变形词词根的词归到一起,最快的方法则是用哈希表。所以这题就是结合哈希表和排序。我们将每个词排序后,根据这个键值,找到哈希表中相应的列表,并添加进去。为了满足题目字母顺序的要求,我们输出之前还要将每个列表按照内部的词排序一下。可以直接用Java的Collections.sort()这个API。

注意:将字符串排序的技巧是先将其转换成一个char数组,对数组排序后再转回字符串

public class Solution {    public List<List<String>> groupAnagrams(String[] strs) {         Map<String, List<String>> map = new HashMap<String, List<String>>();         for(String str : strs){           // 将单词按字母排序             char[] carr = str.toCharArray();             Arrays.sort(carr);             String key = new String(carr);             List<String> list = map.get(key);             if(list == null){             list = new ArrayList<String>();        }        list.add(str);        map.put(key, list);        }         List<List<String>> res = new ArrayList<List<String>>();         // 将列表按单词排序         for(String key : map.keySet()){         List<String> curr = map.get(key);        Collections.sort(curr);        res.add(curr);        }         return res;    }}

六,DP动态规划

Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

public class Solution {    public int climbStairs(int n) {        if(n==1) return 1;        else if(n==2) return 2;        int[] arr=new int[n+1];        arr[1]=1;        arr[2]=2;        for(int i=3;i<=n;i++){        arr[i]=arr[i-1]+arr[i-2];}        return arr[n];     }}
1 0