leetcode 回文问题小结
2017-01-05 16:48
176 查看
leetcode 回文问题小结
1.Palindrome Number
问题描述判断数字是否是回文,空间复杂度O(1)。
解题思路
法一: 将数字转换成字符串,判断一个字符串是否是回文。
public boolean isPalindrome(int x) { if(x < 0) return false; if(x == 0) return true; if(x/10==0) return true; String str = x + ""; int i = 0; while(i < str.length()/2){ if(str.charAt(i)!=str.charAt(str.length()-1-i)) return false; i++; } return true; }
法二:获得reverse之后的数字,如果两个数字相同,则是回文。
public boolean isPalindrome(int x) { if(x < 0) return false; if(x == 0) return true; if(x/10==0) return true; int pre = x; int ret = 0; while(x != 0){ ret = ret * 10 + x%10; x /= 10; } return ret==pre ? true : false; }
2.Palindrome Linked List
问题描述判断单链表是不是回文,时间复杂度O(n),空间复杂度O(1)。
解题思路
将链表前一半反转,中间值为头指针,头变成尾,如果与后半部分相同,就是回文链表,会破坏链表结构。改进:用快慢指针求链表中点。
public boolean isPalindrome(ListNode head) { if(head == null || head.next ==null) return true; int length = getLength(head); int leftEnd = length/2; ListNode pre = null; for(int k = 0; k < leftEnd; k++){ ListNode var = head.next; head.next = pre; pre = head; head = var; } if(length%2!=0) head = head.next; while(pre != null && head != null){ System.out.println(pre.val+":"+head.val); if(pre.val != head.val){ return false; } pre = pre.next; head = head.next; } return (pre == null && head == null) ? true : false; } public int getLength(ListNode head){ int count = 0; while(head!=null){ count++; head = head.next; } return count; }
3.Shortest Palindrome
问题描述给定一个字符串S,你可以通过在它前面添加字符将它转换为回文。 查找并返回通过执行此转换可以找到的最短回文。
解题思路
找到S中以字符串首位为开头的最长回文,将剩余部分反序后添加到S的头部。查找最长回文时,从中间向两边查找。
public String shortestPalindrome(String s) { if(s.length()==0 ||s.length()==1) return s; String ret = ""; int center = (s.length()-1)/2; for(int j = center; j>=0;j--){ if(s.charAt(j) == s.charAt(j+1)) if((ret = isPalindrome(s,j,j+1))!=null) break; if((ret = isPalindrome(s,j,j))!=null) break; } return ret+s; } public String isPalindrome(String s,int left,int right) { int i = 0; for(; left-i>=0 && right+i<s.length();i++){ if(s.charAt(left-i) != s.charAt(right+i)) break; } if((left-i)>=0) return null; StringBuffer sb = new StringBuffer(s.substring(right+i)); return sb.reverse().toString(); }
4.Palindrome Partitioning
问题描述给定一个字符串s,分割s使得分割的每个子字符串是一个回文。返回s的所有可能的回文分割。
解题思路
递归方法
List<List<String>> listAll = new ArrayList<>(); public List<List<String>> partition(String s) { if(s == null || s.length() == 0) return listAll; List<String> var = new ArrayList<>(); if(s.length() == 1){ var.add(s); listAll.add(var); return listAll; }else{ getPartition(s,var); } return listAll; } public void getPartition(String s, List<String> list){ if(s.length() == 0) listAll.add(list); if(s.length() == 1){ list.add(s); listAll.add(list); return; } int n = s.length(); for(int i = 1; i <= n; i++){ String str = s.substring(0,i); if(isPalindrome(str)){ List<String> varList = new ArrayList<>(); if(list.size() != 0){ for(String varStr : list){ varList.add(varStr); } } varList.add(str); getPartition( s.substring(i,n),varList); } } } public boolean isPalindrome(String s){ if(s.length() == 1){ return true; } int i = 0, j = s.length() - 1; while(i <= j){ if(s.charAt(i) != s.charAt(j)) return false; i++; j--; } return true; }
优化后:
List<List<String>> resultLst; ArrayList<String> currLst; public List<List<String>> partition(String s) { resultLst = new ArrayList<List<String>>(); currLst = new ArrayList<String>(); backTrack(s,0); return resultLst; } public void backTrack(String s, int l){ if(currLst.size()>0 //the initial str could be palindrome && l>=s.length()){ List<String> r = (ArrayList<String>) currLst.clone(); resultLst.add(r); } for(int i=l;i<s.length();i++){ if(isPalindrome(s,l,i)){ if(l==i) currLst.add(Character.toString(s.charAt(i))); else currLst.add(s.substring(l,i+1)); backTrack(s,i+1); currLst.remove(currLst.size()-1); } } } public boolean isPalindrome(String str, int l, int r){ if(l==r) return true; while(l<r){ if(str.charAt(l)!=str.charAt(r)) return false; l++;r--; } return true; }
5.Valid Palindrome
问题描述给定一个字符串,确定它是否是回文的,仅仅考虑其中的数字和字符并忽略其他。
例如,
“A man, a plan, a canal: Pannama” 是回文的。
“race a car” 不是回文。
解题思路
定义空字符串是回文,将首位空格去掉,使用两个指针,头指针和尾指针,指向空格时跳过。
public boolean isPalindrome(String s) { if(s.length()<=1) return true; int i = 0, j = s.length() - 1; while(i <= j){ while(i<=j && !isAlNum(s.charAt(i))) i++; while(i<=j && !isAlNum(s.charAt(j))) j--; if(i <= j){ String str1 = s.charAt(i)+""; String str2 = s.charAt(j)+""; if(str1.compareToIgnoreCase(str2)!=0) return false; } i++; j--; } return true; } public boolean isAlNum(char ch){ int asc = (int)ch; if((asc >= 48 && asc <= 57) || (asc >= 65 && asc <= 90) || (asc >= 97 && asc <= 122)) return true; return false; }
法二:先将字符串的空格去掉,都变成小写格式
public boolean isPalindrome(String s) { if(s == null) return false; s = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase(); if(s.length()<=1) return true; int i = 0, j = s.length() - 1; while(i <= j){ if(s.charAt(i) != s.charAt(j)) return false; i++; j--; } return true; }
6.Longest Palindrome
问题描述给定一个由小写或大写字母组成的字符串,找到可以用这些字母构建的最长回文的长度。区分大小写,Aa不是
解题思路
字母出现偶数次的都可以加到回文中。奇数次的要-1。
public int longestPalindrome(String s) { if(s == null) return 0; if(s.length()<=1) return s.length(); HashMap<Character,Integer> map = new HashMap<>(); int sum = 0; boolean flag = false; for(int i = 0; i < s.length(); 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(Integer value : map.values()){ if(value%2 == 0) sum += value; else{ flag = true; sum += value - 1; } } return flag ? sum + 1 : sum; }
7.Longest Palindromic Substring
问题描述给定一个字符串s,在s中找到最长的回文子串。 您可以假设s的最大长度为1000。 如 “babad” 的输出是 “bab”或者“aba”
解题思路
暴力求解:穷举思路:取出所有的子串,判断它是否回文,并返回最长的子串。
动态规划:用boolean[i][j]=true 表示字符串从i到j的子串是回文串,当 pali[i+1][j-1] == true && s.charAt(i)==s.charAt(j)时,pali[i][j] = true;否则为false
空间、时间复杂度 O(n2)
public String longestPalindrome(String s) { //时间o(n2) 空间o(n2) 动态规划 if(s.length()==0 || s.length()==1) return s; int max = 0; String ret = ""; boolean pali[][] = new boolean[s.length()][s.length()]; for(int i = 0; i < s.length(); i++){ for(int j = 0; j < s.length(); j++){ pali[i][j] = false; } } for(int i = 0; i < s.length(); i++){ pali[i][i] = true; if(i < (s.length()-1)){ if(s.charAt(i)==s.charAt(i+1)) pali[i][i+1] = true; else{ pali[i][i+1] = false; } } } for(int i = s.length()-1; i >= 0; i--){ for(int j = s.length()-1; j >= i; j--){ if(pali[i][j] == true){ if(max < (j - i + 1)){ max = j - i + 1; ret = s.substring(i,j+1); } continue; } if((j - i) ==1) continue; if( pali[i+1][j-1] == true && s.charAt(i)==s.charAt(j)){ pali[i][j] = true; if(max < (j - i + 1)){ max = j - i + 1; ret = s.substring(i,j+1); } } else pali[i][j] = false; } } return ret; }
Manacher算法:
相关文章推荐
- 【 Javascript刷LeetCode系列】5. Longest Palindromic Substring 最长回文子串问题
- [Leetcode] 回文问题
- [LeetCode] Palindrome Number & Valid Palindrome - 回文系列问题
- LeetCode总结,动态规划问题小结
- Leetcode全回文问题
- LeetCode总结,二叉树各种类型问题小结
- 【LeetCode】5.Longest Palindromic Substring 最长回文子串问题
- Leetcode516.+Leetcode96. DP问题之求解最长回文子串+BST数目
- [LeetCode系列] 最长回文子串问题
- 【LeetCode】leetcode sum问题汇总小结
- IPC多核入门编程C6657双核启动问题小结
- Mybatis ReflectionException:There is no getter for property named 遇到的问题小结
- leetcode 15. 3Sum 以及2Sum的问题的处理和求解
- Js+Jquery+bootstrap问题小结
- 【Leetcode】:51. N-Queens 问题 in JAVA
- Hibernate使用过程碰到的一些问题小结
- LeetCode 列表合并问题
- jquery.mobile 共同布局遇到的问题小结
- WCF使用问题小结
- Android Studio 简单介绍和使用问题小结