【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”也被认为是正确的
https://gist.github.com/zrqsmcx/7098713 没有用状态转移表的有限状态机解法。
http://www.cnblogs.com/chasuner/p/validNumber.html 带状态转移表的有限状态机解法,很简练。里面有对状态机个状态及合法输入的说明讲解。
http://blog.csdn.net/fightforyourdream/article/details/12900751 给出了一种取巧的正则表达式匹配方法,同时也写了一个暴力解法(就是各种判断的解法)。且有很多其他链接。
http://www.wangqifox.cn/wordpress/?p=437 比较简练的普通方法,搞懂这个也很不错。
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]; }}
- 【Leetcode】String
- LeetCode:String
- LeetCode-String
- LeetCode: Interleaving String
- LeetCode Interleaving String
- LeetCode: Interleaving String
- [Leetcode] Interleaving String
- LeetCode : Scramble String
- [LeetCode] Interleaving String
- [LeetCode] Scramble String
- leetcode 68: Interleaving String
- leetcode 82: Multiply String
- [LeetCode] Scramble String
- [Leetcode] Interleaving String
- [Leetcode] Scramble String
- [LeetCode] Interleave String
- [leetcode] Scramble String
- LeetCode - Interleaving String
- CentOS Linux 上安装svn服务器
- 第13周——Dijkstra算法的验证
- 最大子数组和
- HDOJ 2094 产生冠军 (拓扑排序)
- UML学习(二)
- 【Leetcode】String
- Linear Regression 实现 (Python)
- 完全自定义View
- 黑马程序员——OC语言——@property和@synthesize使用
- 《C++ primer》英文第五版阅读笔记(十八)——成员运算符和条件运算符
- 神经网络的基本原理及编程入门
- iOS学习之场景跳转的三种方式
- Python中遇到的错误(随时更新)
- HDOJ 3342 Legal or Not (拓扑排序)