package yx.csdn.algorithm; //计算逆波兰表达式的值 /**Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 题目大意:给定一个逆波兰表达式,求该表达式的值 思路:由于逆波兰表达式本身不需要括号来限制哪个运算该先进行,因此可以直接利用栈来模拟计算: 遇到操作数直接压栈,碰到操作符直接取栈顶的2个操作数进行计算(注意第一次取出来的是右操作数), 然后再把计算结果压栈,如此循环下去。最后栈中剩下的唯一一个元素便是整个表达式的值 */ import java.util.Stack; public class Test1 { public static void main(String[] args) { String[] tokens = new String[] {"4", "13", "5", "/", "+"}; System.out.println(evalRPN(tokens)); } public static int evalRPN(String[] tokens) { int returnValue = 0; String operators = "+-*/"; Stack<String> stack = new Stack<String>(); for(String t : tokens){ if(!operators.contains(t)){ stack.push(t); }else{ int a = Integer.valueOf(stack.pop());//右操作数 int b = Integer.valueOf(stack.pop());//左操作数 int index = operators.indexOf(t); switch(index){ case 0://+ stack.push(String.valueOf(a+b)); break; case 1://- stack.push(String.valueOf(b-a)); break; case 2://* stack.push(String.valueOf(a*b)); break; case 3:// / stack.push(String.valueOf(b/a)); break; } } } returnValue = Integer.valueOf(stack.pop()); return returnValue; } }
</pre><pre name="code" class="java">
package yx.csdn.algorithm; //最长子回文串 /**推荐使用最后一种方法:中心扩展法(好理解) * 求解最长回文子串的问题最近经常遇到,特别是近期的笔试,因而有了一个学习的契机。 * 先说说回文字符串,回文字符串的意思是从左往右看和从右往左看都是一样的,即我们如果以中心为轴, * 这个字符串是左右对称的,如字符串"abcba","abba"。字符串"abcba"有奇数个字符, * 所以以中间字符'c'为轴左右对称,而字符串"abba"有偶数个字符,所以是对半开来对称的。 * 而顾名思义,最长回文子串就是指一个字符串中最长的具有回文性质的子串了。 * */ public class Test2 { public static void main(String[] args) { fun3(); } private static void fun3() { String s="ewewqewewjjdsjhqwewqsfhjidsfjidshfi"; System.out.println(longestPalindrome3(s)); } /** * 中心扩展法 因为回文字符串是以中心轴对称的,所以如果我们从下标 i 出发,用2个指针向 i 的两边扩展判断是否相等,那么只需要对0到 n-1的下标都做此操作,就可以求出最长的回文子串。但需要注意的是,回文字符串有奇偶对称之分,即"abcba"与"abba"2种类型, 因此需要在代码编写时都做判断。 设函数int Palindromic ( string &s, int i ,int j) 是求由下标 i 和 j 向两边扩展的回文串的长度,那么对0至n-1的下标,调用2次此函数: int lenOdd = Palindromic( str, i, i ) 和 int lenEven = Palindromic (str , i , j ),即可求得以i 下标为奇回文和偶回文的子串长度。 接下来以lenOdd和lenEven中的最大值与当前最大值max比较即可。 这个方法有一个好处是时间复杂度为O(n2),且不需要使用额外的空间。 代码如下,欢迎指导交流~ */ public static String longestPalindrome3(String s) { if (s.isEmpty()) { return null; } if (s.length() == 1) { return s; } String longest = s.substring(0, 1); for (int i = 0; i < s.length(); i++) { // get longest palindrome with center of i String tmp = helper(s, i, i); if (tmp.length() > longest.length()) { longest = tmp; } // get longest palindrome with center of i, i+1 tmp = helper(s, i, i + 1); if (tmp.length() > longest.length()) { longest = tmp; } } return longest; } // Given a center, either one letter or two letter, // Find longest palindrome public static String helper(String s, int begin, int end) { while (begin >= 0 && end <= s.length() - 1 && s.charAt(begin) == s.charAt(end)) { begin--; end++; } return s.substring(begin + 1, end); } }
package yx.csdn.algorithm; import java.util.HashSet; import java.util.Set; /** * * 题目:单词分割问题 * * Given a string s and a dictionary of words dict , determine if s can be * segmented into a space-separated sequence of one or more dictionary words. * * For example, given s = "leetcode" , dict = ["leet", "code"] . * * Return true because "leetcode" can be segmented as "leet code" . * * 分析: * * 一开始看到这个题目,我的第一反应是要递归,但是之后感觉递归的做法估计没办法通过, 然后就开始想,之后看到别人的思路之后,感觉其实还挺容易的。 * * 解题思路: * * 一个字符串S,它的长度为N,如果S能够被“字典集合”(dict)中的单词拼接而成,那么所要满足的条件为: * * F(0, N) = F(0, i) && F(i, j) && F(j, N); * * 这样子,如果我们想知道某个子串是否可由Dict中的几个单词拼接而成就可以用这样的方式得到结果 (满足条件为True, 不满足条件为False) * 存入到一个boolean数组的对应位置上,这样子, 最后boolean数组的最后一位就是F(0, N)的值, * 为True表示这个字符串S可由Dict中的单词拼接,否则不行! * * 解决方案来自 http://www.tuicool.com/articles/Iv2QJf */ public class Test3 { public static void main(String[] args) { String s = "leetcode"; Set<String> dict = new HashSet<String>(); dict.add("leet"); dict.add("code"); System.out.println(wordBreak2(s, dict)); } //given s = "leetcode" , dict = ["leet", "code"] //[0 1 2 3 4 5 6 7 8] //[1 0 0 0 1 0 0 0 1] public static boolean wordBreak2(String s, Set<String> dict) { int len = s.length(); boolean[] arrays = new boolean[len + 1]; arrays[0] = true; for (int i = 1; i <= len; ++i) { for (int j = 0; j < i; ++j) { if (arrays[j] && dict.contains(s.substring(j, i))) { // f(n) = f(0,i) + f(i,j) + f(j,n) arrays[i] = true; break; } } } return arrays[len]; } }
package yx.csdn.algorithm; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; //字梯 /** * *Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that: *Only one letter can be changed at a time *Each intermediate word must exist in the dictionary *For example, *Given: *start = "hit" *end = "cog" *dict = ["hot","dot","dog","lot","log"] *As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", *return its length 5. * * *解决方案:http://www.programcreek.com/2012/12/leetcode-word-ladder/ 感觉就是每次换一个字母 */ public class Test4 { public static void main(String[] args) { String start="hit"; String end="cog"; Set<String> set=new HashSet<String>(); set.add("hot"); set.add("dot"); set.add("dog"); set.add("lot"); set.add("log"); System.out.println(ladderLength(start, end, set)+""); } public static int ladderLength(String start, String end, Set<String> dict) { if (dict.size() == 0) return 0; LinkedList<String> wordQueue = new LinkedList<String>(); LinkedList<Integer> distanceQueue = new LinkedList<Integer>(); wordQueue.add(start); distanceQueue.add(1); while(!wordQueue.isEmpty()){ String currWord = wordQueue.pop(); Integer currDistance = distanceQueue.pop(); for(int i=0; i<currWord.length(); i++){ char[] currCharArr = currWord.toCharArray(); for(char c='a'; c<='z'; c++){ currCharArr[i] = c; String newWord = new String(currCharArr); if(newWord.equals(end)){ return currDistance+1; }else if(dict.contains(newWord)){ wordQueue.add(newWord); distanceQueue.add(currDistance+1); dict.remove(newWord); } } } } return 0; } }
package yx.csdn.algorithm; /** * This problem can be converted to the problem of finding kth element, k is (A's length + B' Length)/2. If any of the two arrays is empty, then the kth element is the non-empty array's kth element. If k == 0, the kth element is the first element of A or B. For normal cases(all other cases), we need to move the pointer at the pace of half of an array length. * @author yixiang *转化成求第K小数问题 */ public class Test5 { public static void main(String[] args) { int ar1[] = {1, 12, 15, 26, 38}; int ar2[] = {2, 13, 17, 30, 45}; System.out.println(findMedianSortedArrays(ar1, ar2)); } public static double findMedianSortedArrays(int A[], int B[]) { int m = A.length; int n = B.length; if ((m + n) % 2 != 0) // odd return (double) findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1); else { // even return (findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1) + findKth(A, B, (m + n) / 2 - 1, 0, m - 1, 0, n - 1)) * 0.5; } } //求第K小数 public static int findKth(int A[], int B[], int k, int aStart, int aEnd, int bStart, int bEnd) { int aLen = aEnd - aStart + 1; int bLen = bEnd - bStart + 1; // Handle special cases if (aLen == 0) return B[bStart + k]; if (bLen == 0) return A[aStart + k]; if (k == 0) return A[aStart] < B[bStart] ? A[aStart] : B[bStart]; int aMid = aLen * k / (aLen + bLen); // a's middle count int bMid = k - aMid - 1; // b's middle count // make aMid and bMid to be array index aMid = aMid + aStart; bMid = bMid + bStart; if (A[aMid] > B[bMid]) { k = k - (bMid - bStart + 1); aEnd = aMid; bStart = bMid + 1; } else { k = k - (aMid - aStart + 1); bEnd = bMid; aStart = aMid + 1; } return findKth(A, B, k, aStart, aEnd, bStart, bEnd); } }
package yx.csdn.algorithm; /** * * @author yixiang *'.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") return false isMatch("aa","aa") return true isMatch("aaa","aa") return false isMatch("aa", "a*") return true isMatch("aa", ".*") return true isMatch("ab", ".*") return true isMatch("aab", "c*a*b") return true */ public class Test6 { public static void main(String[] args) { String s="aab"; String p="aa."; System.out.println(isMatch(s, p)); } public static boolean isMatch(String s, String p) { if(p.length() == 0) return s.length() == 0; //p's length 1 is special case if(p.length() == 1 || p.charAt(1) != '*'){ if(s.length() < 1 || (p.charAt(0) != '.' && s.charAt(0) != p.charAt(0))) return false; return isMatch(s.substring(1), p.substring(1)); }else{ int len = s.length(); int i = -1; while(i<len && (i < 0 || p.charAt(0) == '.' || p.charAt(0) == s.charAt(i))){ if(isMatch(s.substring(i+1), p.substring(2))) return true; i++; } return false; } } }
package yx.csdn.algorithm; import java.util.ArrayList; import java.util.List; /** * 螺旋矩阵 * @author yixiang *Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. For example, given the following matrix: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] You should return [1,2,3,6,9,8,7,4,5]. */ public class Test7 { public static void main(String[] args) { int[][] matrix=new int[][]{ {1,2,3}, {4,5,6}, {7,8,9} }; List<Integer> list=spiralOrder(matrix); for (Integer integer : list) { System.out.println(integer.toString()); } } public static ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> result = new ArrayList<Integer>(); if(matrix == null || matrix.length == 0) return result; int m = matrix.length; int n = matrix[0].length; int x=0; int y=0; while(m>0 && n>0){ //if one row/column left, no circle can be formed if(m==1){ for(int i=0; i<n; i++){ result.add(matrix[x][y++]); } break; }else if(n==1){ for(int i=0; i<m; i++){ result.add(matrix[x++][y]); } break; } //below, process a circle //top - move right for(int i=0;i<n-1;i++){ result.add(matrix[x][y++]); } //right - move down for(int i=0;i<m-1;i++){ result.add(matrix[x++][y]); } //bottom - move left for(int i=0;i<n-1;i++){ result.add(matrix[x][y--]); } //left - move up for(int i=0;i<m-1;i++){ result.add(matrix[x--][y]); } x++; y++; m=m-2; n=n-2; } return result; } }