左程云算法Day9 补充算法

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));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值