Java常用算法
2017-06-21
1 去重
1.1 去重
1.2 去不重
2 隨機分配
3 遞歸
4 內部排序變形
4.1 取數組中未出現的最小整數
5 字符串
5.1 全排序
5.2 找最大回文
5.3 字符串轉換為數字
5.4 和為指定值的兩個數
5.5 字符串是否對應
5.6 出現頻率最高10位數
1 去重
1.1 去重
//去重復,需要額外定義一個List public static void RemoveRepeat(List<Integer> arrs) { List<Integer> tmp = new ArrayList<Integer>(); Iterator<Integer> it = arrs.iterator(); while (it.hasNext()) { int a = it.next(); if (tmp.contains(a)) it.remove(); else tmp.add(a); } }
1.2 去不重
// 去不重復的數,用的是選擇排序算法變化版 public static void RemoveNoRepeat(List<Integer> arrs) { Boolean isRepeate = false; for (int i = 0; i < arrs.size(); i++) { isRepeate = false; for (int j = 0; j < arrs.size(); j++) { if (arrs.get(i) == arrs.get(j) && i != j) { isRepeate = true; break; } } if (!isRepeate) { arrs.remove(i); i--; } } } public static void RemoveNoRepeatImprove(List<Integer> arrs) { Boolean isRepeate = false; for (int i = arrs.size() - 1; i >= 0; i--) { isRepeate = false; for (int j = arrs.size() - 1; j >= 0; j--) { if (arrs.get(i) == arrs.get(j) && i != j) { isRepeate = true; break; } } if (!isRepeate) { arrs.remove(i); } } } public static void RemoveNoRepeatWithExtraMap(List<Integer> arrs) { Map<Integer, Integer> repeat = CountRepeat(arrs); for (int i = arrs.size() - 1; i >= 0; i--) { if (repeat.get(arrs.get(i)) == 1) { arrs.remove(i); } } } // 統計重復數 public static Map<Integer, Integer> CountRepeat(List<Integer> arrs) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); Integer value = 0; for (Integer arr : arrs) { if (map.containsKey(arr)) { value = map.get(arr); map.put(arr, value + 1); } else { map.put(arr, 1); } } return map; }
HashMap實現

public static void RemoveNotRepeat(List<Character> arrs) { Map<Character,Integer> tmp=new HashMap(); for(char c:arrs) { if(tmp.containsKey(c)) tmp.put(c,tmp.get(c)+1); else tmp.put(c,1); } Iterator<Character> it=arrs.iterator(); while (it.hasNext()) { Character c=it.next(); if(tmp.get(c)==1) it.remove(); } }
2 隨機分配
public static Map<String, String> TicketDispatch(List<String> customers, List<String> tickets) { Map<String, String> result = new HashMap<String, String>(); Random r = new Random(); int iCustomer; int iTicket; for (int i = customers.size(); i > 0; i--) { // 取值范圍[0,i) iCustomer = r.nextInt(i); iTicket = r.nextInt(tickets.size()); result.put(customers.get(iCustomer), tickets.get(iTicket)); customers.remove(iCustomer); tickets.remove(iTicket); } return result; }
3 遞歸
//Java遞歸刪除一個目錄下文件和文件夾 private static void deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); // 遞歸刪除目錄中的子目錄下 for (int i=0; i<children.length; i++) { deleteDir(new File(dir, children[i])); } } dir.delete(); }
4 內部排序變形
4.1 取數組中未出現的最小整數
public static Integer GetNotExitMinInteger(Integer[] arr) { Integer minIndex; Integer tmp; Integer first=0; for(int i=0;i<arr.length;i++) { minIndex=i; for(int j=i+1;j<arr.length;j++) { if(arr[minIndex]>arr[j]) minIndex=j; } if(arr[minIndex]-first>1) return first+1; else { first=arr[minIndex]; } if(minIndex!=i) { tmp=arr[i]; arr[i]=arr[minIndex]; arr[minIndex]=tmp; } } return arr[arr.length-1]+1; }
上面問題其他解決方案:
也可先排序(快速排序,若范圍可確定,且不到,可用桶排序),在先后比較arr[next]-arr[one]>1
HashMap實現

public static Integer GetNotExitMinIntegerByHashMap(Integer[] arr) { Integer minKey=Integer.MAX_VALUE; Integer maxKey=Integer.MIN_VALUE; Map<Integer,Integer> map=new HashMap<Integer,Integer>(); for(int i=0;i<arr.length;i++) { map.put(arr[i],arr[i]); if(minKey>arr[i]) minKey=arr[i]; if(maxKey<arr[i]) maxKey=arr[i]; } Integer pre=minKey; if(minKey>1) return minKey-1; while(pre<=maxKey) { if(map.get(pre+1)==null) return pre+1; else ++pre; } return maxKey+1; }
5 字符串
5.1 全排序
思路:
n個字符
- 前n-1個固定,第n個,不能再互換,打印排列
- 前n-2個固定,第n-1個和n位置互換,得到排列
- 前n-3個固定,第n-2個分別和最后兩個位置互換
- ...

public class FullPermutation { public static void main(String[] args) { char[] arr=new char[]{'A','B','C','D'}; Permutatition(arr); } public static void Permutatition(char[] arr) { recursivePermutation(arr,0,arr.length-1); } private static void recursivePermutation(char[] arr,int start,int end) { if(start==end) { for (int i = 0; i <= end; i++) System.out.print(arr[i]); System.out.println(); } else { for (int i = start; i <= end; i++) { swap(arr, start, i); recursivePermutation(arr, start+1, end); swap(arr, start, i); } } } private static void swap(char[] arr,int left,int right) { char tmp=arr[left]; arr[left]=arr[right]; arr[right]=tmp; } }
5.2 找最大回文
回文:正讀,倒讀一樣
樣例:abcdedcba,abcddcba
思路:中心點,看兩邊是否對應

public static String longestPalindrome(String str) { if(str==null||str.length()==0) return ""; int max=0,current=0,length=str.length(); String subString=""; for(int i=0;i<length;i++) { //考慮回文字段為奇數長度 for(int j=0;i-j>=0&&i+j<length;j++) { if(str.charAt(i-j)!=str.charAt(i+j)) break; current=j*2+1; } if(current>max) { max=current; subString=str.substring(i-max/2,i+max/2+1); } //考慮回文字段為偶數長度 for(int j=0;i-j>=0&&i+j+1<length;j++) { if(str.charAt(i-j)!=str.charAt(i+j+1)) break; current=j*2+2; } if(current>max) { max=current; subString=str.substring(i-max/2+1,i+max/2+1); } } return subString; }
5.3 字符串轉換為數字

public static int toInt(String str) { if(str==null&&str.length()==0) throw new RuntimeException("字符串為空"); //轉換結果 int result=0; //要轉換的字符 int current=0; //整數的正負 char sign='+'; if(str.charAt(0)=='-'||str.charAt(0)=='+') { sign=str.charAt(0); str=str.substring(1); } //是否需要判斷 boolean judgeOverflow=true; if(str.length()>10) { throw new RuntimeException("整形溢出了"); } else if(str.length()<10) { judgeOverflow=false; } for(int i=0;i<str.length();i++){ current=str.charAt(i)-'0'; if(current>9||current<0) throw new RuntimeException("包含非整數型字符"); if(judgeOverflow) { if(sign=='+'&¤t>Integer.MAX_VALUE/(int)Math.pow(10,9-i)%10) { throw new RuntimeException("整形溢出了"); } if(sign=='-'&¤t>Math.abs(Integer.MIN_VALUE/(int)Math.pow(10,9-i)%10)) { throw new RuntimeException("整形溢出了"); } } result=result*10+current; } if(sign=='-') { result=-result; } return result; }
5.4 和為指定值的兩個數
思路
1 先排序,后加
2 用哈希表,key為數的值,value為位置。這樣,hashMap.get(sum-arr[i]),O(1)定位

public class TwoSum { public static void main(String[] args) { int[] arr=new int[]{7,8,5,4,1,2,3,6,9}; findByHash(arr,10); int[] arr2=new int[]{1,2,3,4,5,6,7,8,9}; find(arr2,10); } public static void find(int[] arr,int sum) { //arr 這里arr是排好序的了 int begin=0; int end=arr.length-1; while(begin<end) { if(arr[begin]+arr[end]==sum) { System.out.println(String.format(("[%d,%d]"), arr[begin], arr[end])); begin++; } else if(arr[begin]+arr[end]>0)end--; else begin++; } } public static void findByHash(int[] arr, int sum) { Hashtable<Integer,Integer> hashMap=new Hashtable<>(); for(int i=0;i<arr.length;i++) { hashMap.put(arr[i],i); } for(int i=0;i<arr.length;i++) { int index=hashMap.get(sum-arr[i]); if(index!=-1&&index>i) { System.out.println(String.format(("[%d,%d]"), arr[i], arr[index])); } } } }
5.5 字符串是否對應
1 pattern="aabac"
2 target="dog dog pig dog cat"
3 target=="dog dog pig dog dog"
1、2模式一致,1、3模式不一致

public static boolean isPatternMatch(String pattern,String target) { Map<Character,String> mPatternTarget=new HashMap<>(); char[] cPattern=pattern.toCharArray(); String[] strTarget=target.split(" "); for(int i=0;i<cPattern.length;i++) { if(!mPatternTarget.containsKey(cPattern[i])) mPatternTarget.put(cPattern[i],strTarget[i]); else { if(!mPatternTarget.get(cPattern[i]).equals(strTarget[i])) return false; } } return true; }
5.6 出現頻率最高10位數
hashmap按值,按排序

public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("c", "ccccc"); map.put("a", "aaaaa"); map.put("b", "bbbbb"); map.put("d", "ddddd"); List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet()); Collections.sort(list,new Comparator<Map.Entry<String,String>>() { //升序排序 public int compare(Entry<String, String> o1, Entry<String, String> o2) { return o1.getValue().compareTo(o2.getValue()); } }); for(Map.Entry<String,String> mapping:list){ System.out.println(mapping.getKey()+":"+mapping.getValue()); } }
Lambda簡化版

public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("c", "ccccc"); map.put("a", "daaaa"); map.put("b", "bbbbb"); map.put("d", "ddddd"); List<Map.Entry<String, String>> list=new ArrayList<Map.Entry<String,String>>(map.entrySet()); list.sort((o1,o2)-> o1.getValue().compareTo(o2.getValue())); for(Map.Entry<String,String> mapping:list){ System.out.println(mapping.getKey()+":"+mapping.getValue()); } }