dijksra加速:
不使用遍历的方法而使用小根堆实现。但是这个堆需要自己重写
mport java.util.HashMap;
/**
* @author 咕噜大飞侠
* @version 1.0
* Create by 26/2/2022 下午5:56
*/
public class NewDijkstra{
public static HashMap<Node,Integer> newDijkstra(Node head,int size){//用hashmap返回到达的节点以及最短的距离
NodeHeap nodeHeap = new NodeHeap(size);
nodeHeap.addOrUpdateOrIgnore(head,0);//若没有就add,有且现在的距离更短则update,有但是现在的距离更长则ignore
HashMap<Node,Integer> result = new HashMap<>();
while(!nodeHeap.isEmpty()){
NodeRecord record = nodeHeap.pop();
Node cur =record.node;
int distance = record.distance;
for (Edge edge:cur.edges) {
nodeHeap.addOrUpdateOrIgnore(edge.to,edge.weight+distance);//遍历该节点后续的节点吗
}
result.put(cur,distance);
}
return result;
}
public static class NodeRecord{
public Node node;
public int distance;
public NodeRecord(Node node,int distance){
this.node = node;
this.distance = distance;
}
}
public static class NodeHeap{
private Node[] nodes;
private HashMap<Node,Integer> heapIndexMap;//存放堆的节点node的位置
private HashMap<Node,Integer> distanceMap;//存放到各点的距离
private int size;
public NodeHeap(int size){
nodes = new Node[size];//初始化nodes
heapIndexMap =new HashMap<>();
distanceMap = new HashMap<>();
this.size = 0;
}
public boolean isEmpty(){
return size==0;
}
public void addOrUpdateOrIgnore(Node node,int distance){
if(inHeap(node)){ //在堆上,更新
distanceMap.put(node,Math.min(distance,distanceMap.get(node)));
insertHeapify(node,heapIndexMap.get(node));
}
if(!isEntered(node)){//若没有进来过,则在堆尾加上
nodes[size] =node;
heapIndexMap.put(node,size);
distanceMap.put(node,distance);
insertHeapify(node,size++);
}
}
private boolean isEntered(Node node){//是否进来过堆
return heapIndexMap.containsKey(node);
}
private boolean inHeap(Node node){
return isEntered(node)&&heapIndexMap.get(node)!=-1;//-1是标志已经出去了
}
private void swap(int index1,int index2){
heapIndexMap.put(nodes[index1],index2);
heapIndexMap.put(nodes[index2],index1);
/*在heapIndexMap上加入nodes[index1]和[index2]两个数*/
Node temp = nodes[index1];
nodes[index1] =nodes[index2];
nodes[index2]= temp;
}
public NodeRecord pop(){
NodeRecord nodeRecord = new NodeRecord(nodes[0],distanceMap.get(nodes[0]));
heapIndexMap.put(nodes[size-1],-1);
distanceMap.remove(nodes[size-1]);
nodes[size-1]=null;
heapify(0,--size);
return nodeRecord;
}
private void insertHeapify(Node node,int index){
while(distanceMap.get(nodes[index])<distanceMap.get(nodes[(index-1)/2]));
swap(index,(index-1)/2);
index = (index-1)/2;
}
private void heapify(int index,int size){
int left = index*2+1;
while (left<size){
int smallest = left+1<size&&distanceMap.get(nodes[left+1])<distanceMap.get(nodes[size])?
left+1:left;
smallest = distanceMap.get(nodes[smallest])<distanceMap.get(nodes[index])?smallest:index;
if(smallest==index){
break;
}
}
}
}
}
暴力递归:实则为不断尝试
1、把问题转化为规模小了的同类问题的子问题
2、有明确的不需要继续进行递归的条件(base case)
3、有当得到了子问题的结果后的决策过程
4、不记录每一个子问题的解
题目1
经典hanoi盘问题,给n个盘,求出挪动盘的顺序
public class Hanoi {
public static void hanoi(int n){
if (n>0){
fanc(n,"左","右","中");
}
}
public static void fanc(int n,String from,String to,String other){
if (n == 1) {
System.out.println("将盘1从"+from+"移动到"+to);
}
if (n >= 2) {
fanc(n-1,from,other,to);//将前n-1个移动到other
System.out.println("将盘"+n+"从"+from+"移动到"+to);//最后一个移动到to
fanc(n-1,other,from,to);//将n-1个恢复到from
}
}
public static void main(String[] args) {
hanoi(4);
}
}
题目2:打印一个字串的全部子序列,包括空字符
public class PrintSubstring {
public static void printSubstring(String str){
char[] chars = str.toCharArray();//把字符串转换为字符数组便于后续操作
process(chars,0,new ArrayList<Character>());//0代表当前在chars[0]位置
}
public static void process(char[] chars, int n, List<Character> characters){
if(n==chars.length){
print(characters);
return;
}
List keepchar = copyArrayList(characters);
keepchar.add(chars[n]);
process(chars,n+1, keepchar);//添加当前字符的路
List nokeepchar = copyArrayList(characters);
process(chars,n+1, nokeepchar);//不添加当前字符的路
}
public static void print(List<Character> characters){
//略
}
public static List copyArrayList(List<Character> characters){
List<Character> newList = null;
//略
return newList;
}
}
空间优化:利用栈的思想,在string中设置要或者不要
题目3
打印一个字符串的全部排列
打印一个字符串的全部排列,要求不出现重复的排列
import java.util.ArrayList;
/**
* @author 咕噜大飞侠
* @version 1.0
* Create by 27/2/2022 下午6:13
* 打印一个字符串的全部排列
*
* 打印一个字符串的全部排列,要求不出现重复的排列
*/
public class StringPermutation {
public static ArrayList<String> stringArrayList(String string){
if(string==null){
return null;
}
ArrayList<String> res = new ArrayList<>();
char[] str = string.toCharArray();
process(0,str,res);
return res;
}
public static void process(int i,char[] str,ArrayList<String> res){
if(i==str.length){
res.add(String.valueOf(str));
}
boolean[] visited = new boolean[26];//为去重的辅助数组
for(int j =i;j<str.length;j++){
if(!(visited[str[j]-'a'])) {//初始值为false,若这个char之前没有出现过则继续
visited[str[j]-'a']=true;
swap(i, j, str);//先i,j交换
process(i + 1, str, res);//往后走
swap(i, j, str);//交换回来,j++
}
}
}
public static void swap(int i,int j, char[] str){
char temp = str[i];
str[i]=str[j];
str[j]=temp;
}
}
题目4
public class CardInLine {
public static int cardInLine(int[] arr){
if(arr==null||arr.length==0){
return 0;
}
return Math.max(f(arr,0,arr.length-1),s(arr,0,arr.length-1));
}
public static int f(int[] arr,int L,int R){
if(L==R){
return arr[L];
}
return Math.max(arr[L]+s(arr,L+1,R),arr[R]+s(arr,L,R-1));
}
public static int s(int[] arr,int L,int R){
if(L==R){
return 0;
}
return Math.min(f(arr,L+1,R),f(arr,L,R-1));
}
}