算法题总结的几种题型

本文作者分享了刷270道算法题的心得体会,重点介绍了如何将具体题型抽象为组件(component)和数据结构插件(plugin),并结合实例展示了预处理、组件组合、问题转化等解题方法。文章强调了基础知识的重要性,提倡通过牛客网进行分类刷题,并总结了优化代码运行时间和空间的技巧。

前言

刷了270道算法,记录自己的心得体会,主要包括具体题型总结和抽象题型总结。

一、具体题型总结

具体的题型总结就是线性表的数组、链表、队列的操作和应用,树的四种遍历、回溯、剪枝,图的DFS、BFS等,动态规划,前缀树等。

具体可去牛客网完成相应一类知识点的刷题。

二、抽象题型总结

我把每个知识点封装成一个component,如component-DFS、component-动态规划等。把数据结构应用看成plugin来辅助component完成算法题解。两类可自由组合。总结了五种题型。

1、预处理Pre + component

1)单词演变:预处理成图+BFS-component
在这里插入图片描述

	//单向BFS+代码优化,减少运行时间。
    public int ladderLength2(String beginWord, String endWord, List<String> wordList) {
   
   
        //1-预处理:将worldList中的单词作为一个节点,将其之间的关系映射为图关系,然后物理结构预处理成数组式的邻接表。
        //2-BFS操作:通过广度优先搜索来求源点到终点的最短路径。
        for (String s : wordList) addEdge(s);

        if (!wordId.containsKey(endWord)) return 0;
        addEdge(beginWord);

        int begin = wordId.get(beginWord), end = wordId.get(endWord);
        int[] dis = new int[nodeNum];//用该数组既能记住起点到所有节点的最短路径,还能避免加入以访问过的节点避免死循环。
        dis[begin] = 1;

        Queue<Integer> queue = new LinkedList<>();
        queue.offer(begin);

        while (!queue.isEmpty()) {
   
   
            int cur = queue.poll();

            for (Integer id : edge.get(cur)) {
   
   
                if (dis[id] == 0) {
   
   
                    dis[id] = dis[cur] + 1;
                    queue.offer(id);
                }
                if (id == end) return (dis[id] >>> 1) + 1;

            }
        }
        return 0;
    }

    Map<String, Integer> wordId = new HashMap<>();
    List<List<Integer>> edge = new ArrayList<>();
    int nodeNum = 0;

    private void addEdge(String s) {
   
   
        addNode(s);

        int len = s.length();
        char[] chs = s.toCharArray();

        for (int i = 0; i < len; i++) {
   
   
            char originC = chs[i];
            chs[i] = '*';

            String newWord = String.valueOf(chs);
            addNode(newWord);
            int idx1 = wordId.get(s), idx2 = wordId.get(newWord);
            edge.get(idx1).add(idx2);
            edge.get(idx2).add(idx1);

            chs[i] = originC;
        }
    }

    private void addNode(String s) {
   
   
        if (!wordId.containsKey(s)) {
   
   
            wordId.put(s, nodeNum++);
            edge.add(new ArrayList<>());
        }
    }

    //双向BFS,通过减少没必要的distance计算,从而减少计算时间。2^8^ > 2^4^ + 2^4^(毕竟单向广度优先,越往后走,要以指数级扩展。)
    public int ladderLength3(String beginWord, String endWord, List<String> wordList) {
   
   
        for (String s : wordList) addEdge(s);

        if (!wordId.containsKey(endWord)) return 0;
        addEdge(beginWord);

        int begin = wordId.get(beginWord), end = wordId.get(endWord);
        int[] dis1 = new int[nodeNum];//用该数组既能记住起点到所有节点的最短路径,还能避免加入以访问过的节点避免死循环。
        int[] dis2 = new int[nodeNum];
        dis1[begin] = 1;
        dis2[end] = 1;

        Queue<Integer> queue1 = new LinkedList<>();
        Queue<Integer> queue2 = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值