二分查找(while实现即可)easy
package Algorithm;
public class BinarySearchNo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int array[] = {1,3,8,10,11,67,100};
int index = BinarySearch(array,1);
System.out.println(index);
}
public static int BinarySearch(int[] array,int value) {
int left = 0;
int right = array.length - 1;
while(left <= right) {
int mid = (left + right)/2;
if(array[mid] == value) {
return mid;
}else if(array[mid] < value) {
left = mid +1;
}else{
right = mid - 1;
}
}
return -1;
}
}
分治 汉诺塔问题求解
package Algorithm;
public class Hanoitower {
public static void main(String[] args) {
// TODO Auto-generated method stub
hanoiTower(4,'A','B','C');
}
//汉诺塔方法 分治加递归
public static void hanoiTower(int num,char a,char b,char c) {
if(num == 1) {
System.out.println("第1个盘从"+ a +"->" + c);
}else {
//先将num-1个盘从a经过c到b
hanoiTower(num-1, a,c,b);
//将最后一个盘从a到c
System.out.println("第"+ num + "个盘从" + a + "->" + c);
//num-1个盘从b经过a到c
hanoiTower(num-1, a,b,c);
}
}
}
动态规划 背包问题 动态规划问题下一步骤要考虑上一次的决策
package Algorithm;
public class dynamic {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] w = {1,4,3}; //物品的重量
int[] val = {1500,3000,2000};
int n = val.length; //物品的个数
int m = 4;//背包容量
//为了计入放入商品的情况,定义二维数组
int[][] path = new int[n+1][m+1];
//创建二维数组 v v[i][j]表示在前i个物品中能够装入容量我ij的背包中的最大价值
int[][] v = new int[n+1][m+1];
//初始化第一行和第一列
for(int i = 0; i < v.length; i++)
v[i][0] = 0;
for(int i = 0; i < v[0].length; i++)
v[0][i] = 0;
// for(int i = 0; i < v.length; i++) {
// for(int j = 1; j < v[0].length; j++)
// System.out.println(v[i][j]);
// }
for(int i = 1; i < v.length; i++) {
for(int j = 1; j < v[0].length; j++)
if(w[i-1] > j) {
v[i][j] = v[i-1][j];
}else {
//因为是从1 开始的 公式需要调整
//v[i][j] = Math.max(v[i-1][j],val[i-1] + v[i-1][j-w[i-1]]);
//为了记录商品放入背包的情况,不能简单使用上式
if(v[i-1][j] < val[i-1] + v[i-1][j-w[i-1]]) {
v[i][j] = val[i-1] + v[i-1][j-w[i-1]];
path[i][j] = 1;
}else {
v[i][j] = val[i-1];
}
}
}
for(int i = 0; i < v.length; i++) {
for(int j = 1; j < v[0].length; j++) {
System.out.printf(v[i][j] + " ");
}
System.out.println();
}
// for(int i = 0; i < path.length; i++) {
// for(int j = 1; j < path[0].length; j++)
// if(path[i][j] == 1)
// System.out.printf("第%d个商品放入背包\n",i);
// }
// }
//
int i = path.length -1;
int j = path[0].length -1;
while(i >0 && j >0) {
//逆序输出}
if(path[i][j]==1) {
System.out.printf("第%d个商品放入背包\n",i);
j -= w[i-1];
}
i--;
}
}
}
贪心算法的本质是每次寻找最大最好的那一个
package Algorithm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class GreedyAlgorithm {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建广播电台,放入到Map
//将各个电台放入到broadcasts
HashMap<String,HashSet<String>> broadcasts = new HashMap<String,HashSet<String>>();
//将各个电台放入到broadcasts
HashSet<String> hashSet1 = new HashSet<String>();
hashSet1.add("北京");
hashSet1.add("上海");
hashSet1.add("天津");
HashSet<String> hashSet2 = new HashSet<String>();
hashSet2.add("广州");
hashSet2.add("北京");
hashSet2.add("深圳");
HashSet<String> hashSet3 = new HashSet<String>();
hashSet3.add("成都");
hashSet3.add("上海");
hashSet3.add("杭州");
HashSet<String> hashSet4 = new HashSet<String>();
hashSet4.add("天津");
hashSet4.add("上海");
HashSet<String> hashSet5 = new HashSet<String>();
hashSet5.add("杭州");
hashSet5.add("大连");
//加到到Map
broadcasts.put("K1", hashSet1);
broadcasts.put("K2", hashSet2);
broadcasts.put("K3", hashSet3);
broadcasts.put("K4", hashSet4);
broadcasts.put("K5", hashSet5);
//allAreas存放所有的地区
HashSet<String> allAreas = new HashSet<String>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");
//创建ArrayList,存放选择的电台集合
ArrayList<String> selects = new ArrayList<String>();
//定义一个临时的集合,在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
HashSet<String> tempSet = new HashSet<String>();
//定义给maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的Key
//如果maxKey 不为Null,则加入到selects
String maxKey = null;
while(allAreas.size()!= 0) {
//遍历broadcasts,取出对应key
maxKey = null;
for(String key : broadcasts.keySet()) {
//当前这个key能够覆盖的地区
tempSet.clear();
HashSet<String> areas = broadcasts.get(key);
tempSet.addAll(areas);
//求出tempSet和allAread集合的交集,交集会赋给tempSet
tempSet.retainAll(allAreas);
if(tempSet.size() > 0 && ( maxKey == null || tempSet.size() > broadcasts.get(maxKey).size() )) {
maxKey = key;
}
}
if(maxKey != null) {
selects.add(maxKey);
allAreas.removeAll(broadcasts.get(maxKey));
}
}
System.out.println("得到的选择结果是" + selects);
}
}
暴力破解
package Algorithm;
public class ViolenceMatch {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 ="我爱学习 学习爱我吗";
String str2 ="学习爱我";
int index = violenceMatch(str1,str2);
System.out.println("index:" + index);
}
//暴力匹配算法实现
public static int violenceMatch(String str1,String str2) {
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
int s1len = s1.length;
int s2len = s2.length;
int i = 0; //i索引指向s1
int j = 0; //j索引指向s2
while(i < s1len && j < s2len) {
if(s1[i] == s2[j]) {
//匹配成功
i++;
j++;
}else {
//没有匹配成功
i -= j-1;
j = 0;
}
}
if( j == s2len)
return i-j;
else
return -1;
}
}
KMP算法!!!重要!!!难懂
KMP用了两次临时数组。第一次是在要比较的数组中,用来找到数组是否有重复的元素,如题中ABCDABD,AB显然是重复的,所以在匹配不下的情况下,我们可以直接从跳四个进行重新查找,这样就加快了查找效率。所以在要比较的数组中,它的索引是0000 1 2 0 ,这表明只有A B 是可以的。再详细的讲,再kmpNext函数中,一个索引从1开始,一个索引从0开始,由于两个字符不相等,索引从1 开始的一直在++,去匹配索引从0开始的值,一旦匹配到值,则从0开始的索引++,一旦不匹配,将从0开始的索引--,看是否匹配,如果不匹配则再次--,直到j=0(这是一个while循环)。这样就理解了第一个临时数组。如题中的next;第二个临时数组是在实际的比较中,如果发现了不匹配,此时使用next中的索引,直接跳到该去的位置继续查询
package Algorithm;
import java.util.Arrays;
public class KMP {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 = "BBC ABCDAB ABCDABCDABDE";
String str2 = "ABCDABD";
int[] next = kmpNext("ABCDABD");
System.out.println("next=" + Arrays.toString(next));
int index = kmpSearch(str1,str2,next);
System.out.println("index=" + index);
}
//遍历
public static int kmpSearch(String str1,String str2,int[] next) {
//遍历
for(int i = 0, j = 0; i < str1.length(); i++) {
while( j > 0 && str1.charAt(i)!= str2.charAt(j)) {
j = next[j-1];
}
if(str1.charAt(i)== str2.charAt(j))
j++;
if(j == str2.length()) {
return i - j + 1;
}
}
return -1;
}
//获取一个字符串的部分匹配表
public static int[] kmpNext(String dest) {
//创建一个next数组保存有部分匹配表
int[] next = new int[dest.length()];
next[0] = 0;//如果字符串长度为1,部分匹配表就是0
for(int i = 1,j = 0; i < dest.length(); i++) {
//当dest.charAt(i) == dest.charAt(j)
while(j > 0 && dest.charAt(i)!= dest.charAt(j)) {
j = next[j-1];
}
if(dest.charAt(i)== dest.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}
}