专题【链表】【考试题】刷题日记

news2024/11/21 1:30:59

题目列表

考试题(22题)

2024.04.04

146. LRU 缓存
707. 设计链表
138. 随机链表的复制
160. 相交链表
622. 设计循环队列
109. 有序链表转换二叉搜索树
460. LFU 缓存
355. 设计推特
725. 分隔链表
2487. 从链表中移除节点

日常复习题

876. 链表的中间结点
1171. 从链表中删去总和值为零的连续节点
2807. 在链表中插入最大公约数
117. 填充每个节点的下一个右侧节点指针 II
641. 设计循环双端队列
1669. 合并两个链表
114. 二叉树展开为链表
237. 删除链表中的节点
1206. 设计跳表
706. 设计哈希映射
1721. 交换链表中的节点
1019. 链表中的下一个更大节点
2181. 合并零之间的节点
2816. 翻倍以链表形式表示的数字
705. 设计哈希集合
2095. 删除链表的中间节点


2024.04.04

146. LRU 缓存

题目

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例:

输入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

提示:

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 105
  • 最多调用 2 * 105 次 get 和 put

思路

  1. 维护kv(HashMap)
  2. 维护k的使用顺序,(最新的往前挪)(双向链表)

答案

class LRUCache {
    private class Node {
        int key;
        int value;
        Node pre;
        Node next;

        public void removeNode() {
            this.next.pre = this.pre;
            this.pre.next = this.next;
        }
    }

    private Node head;
    private Node tail;
    private int capacity;
    private Map<Integer, Node> map;

    public LRUCache(int capacity) {
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.pre = head;
        this.capacity = capacity;
        map = new HashMap<>();
    }

    private void addToHead(Node node) {
        node.next = head.next;
        head.next = node;
        node.pre = head;
        node.next.pre = node;
    }

    public int get(int key) {
        Node node = map.get(key);
        if (node != null) {
            node.removeNode();
            addToHead(node);
        }
        return Optional.ofNullable(map.get(key)).map(n -> n.value).orElse(-1);
    }

    public void put(int key, int value) {
        if (map.containsKey(key)) {
            Node oldNode = map.get(key);
            oldNode.pre.next = oldNode.next;
            oldNode.next.pre = oldNode.pre;
            map.remove(oldNode.key);
        }

        Node node = new Node();
        node.key = key;
        node.value = value;
        addToHead(node);

        map.put(key, node);
        if (map.size() > capacity) {
            removeTail();
        }
    }

    private void removeTail() {
        Node removeNode = tail.pre;
        removeNode.pre.next = tail;
        tail.pre = removeNode.pre;
        map.remove(removeNode.key);
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

707. 设计链表

题目

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

  • MyLinkedList() 初始化 MyLinkedList 对象。
  • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
  • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
  • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
  • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
  • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

示例:

输入
[“MyLinkedList”, “addAtHead”, “addAtTail”, “addAtIndex”, “get”, “deleteAtIndex”, “get”]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出
[null, null, null, null, 2, null, 3]

解释
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
myLinkedList.get(1); // 返回 2
myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
myLinkedList.get(1); // 返回 3

提示:

  • 0 <= index, val <= 1000
  • 请不要使用内置的 LinkedList 库。
  • 调用 get、addAtHead、addAtTail、addAtIndex 和 deleteAtIndex 的次数不超过 2000 。

思路

  1. 实现个node
  2. 各种边界要判断清除
  3. 要有个虚构的头结点

答案

class MyLinkedList {
    class Node {
        int value;
        Node next;
    }
    private int size;
    private Node dummy;

    public MyLinkedList() {
        size = 0;
        dummy = new Node();
    }
    
    public int get(int index) {
        if (index < 0 || index >= size) {
            return -1;
        }
        Node current = dummy;
        for (int i = 0; i <= index; i++) {
            current = current.next;
        }
        return current.value;
    }
    
    public void addAtHead(int val) {
        Node node = new Node();
        node.value = val;
        node.next = dummy.next;
        dummy.next = node;
        size++;
    }
    
    public void addAtTail(int val) {
        Node node = new Node();
        node.value = val;

        Node current = dummy;
        for (int i = 0; i < size; i++) {
            current = current.next;
        }
        current.next = node;
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if (index > size) {
            return;
        }
        Node node = new Node();
        node.value = val;

        Node current = dummy;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        node.next = current.next;
        current.next = node;
        size++;
    }
    
    public void deleteAtIndex(int index) {
        if (index >= size) {
            return;
        }
        Node current = dummy;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        current.next = current.next.next;
        size--;
    }
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

160. 相交链表

题目

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:
在这里插入图片描述

题目数据 保证 整个链式结构中不存在环。

注意, 函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

  • intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
  • listA - 第一个链表
  • listB - 第二个链表
  • skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
  • skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数
    评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。

示例 1:
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

示例 2:
在这里插入图片描述

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:
在这里插入图片描述

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

提示:

  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 1 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA] == listB[skipB]

进阶: 你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?

思路

假设俩链表相交。
A的长度为A = a + x,x为相交部分长度
B的长度为B = b + x,x为相交部分长度
所以,只需要将两个链表首尾相连
A走到x开头的位移为a + x + b,走完自己又走完B
B走到x开头的位移为b + x + a,走完自己又走完A
长度相同,会在相交节点相遇

答案

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pA = headA, pB = headB;
        while (pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        // 相交就在x的开头,否则最终,两个都为null,返回null
        return pA;
    }
}

725. 分隔链表

题目

给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。
每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。
这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。
返回一个由上述 k 部分组成的数组。

示例 1:
在这里插入图片描述

输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。

示例 2:
在这里插入图片描述

输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3
输出:[[1,2,3,4],[5,6,7],[8,9,10]]
解释:
输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。

提示:

  • 链表中节点的数目在范围 [0, 1000]
  • 0 <= Node.val <= 1000
  • 1 <= k <= 50

思路

  1. 10个节点是4, 3, 3。是10 / 3 = 3。3组3个节点的,从前往后10 % 3 = 1,从前向后加1。即(3+1), 3, 3
  2. 断开节点,所以拿前一个节点
  3. 按照个数断开

答案

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode[] splitListToParts(ListNode head, int k) {
        int size = 0;
        ListNode current = head;
        while (current != null) {
            size++;
            current = current.next;
        }
        /// 算个数
        int mod = size % k;
        int minSize = size / k;
        current = head;
        ListNode[] result = new ListNode[k];
        for (int i = 0; i < k; i++) {
            int l = 0;
            int length = minSize + (i < mod ? 1 : 0);
            result[i] = current;
            // 拿到前一个节点
            while (l++ < length - 1) {
                if (current != null) {
                    current = current.next;
                }
            }
            // 处理边界
            if (current == null) {
                return result;
            }
            // 断开
            ListNode next = current.next;
            current.next = null;
            current = next;
        }
        return result;
    }
}

2487. 从链表中移除节点

题目

给你一个链表的头节点 head 。
移除每个右侧有一个更大数值的节点。
返回修改后链表的头节点 head 。

示例 1:
在这里插入图片描述

输入:head = [5,2,13,3,8]
输出:[13,8]
解释:需要移除的节点是 5 ,2 和 3 。

  • 节点 13 在节点 5 右侧。
  • 节点 13 在节点 2 右侧。
  • 节点 8 在节点 3 右侧。

示例 2:

输入:head = [1,1,1,1]
输出:[1,1,1,1]
解释:每个节点的值都是 1 ,所以没有需要移除的节点。

提示:

  • 给定列表中的节点数目在范围 [1, 105] 内
  • 1 <= Node.val <= 105

思路

其实是,返回一个非递增的数组。
《移除每个右侧有一个更大值的节点》,意味着最右边的节点不会动(一定会保留)。
所以反转下,就是一个以第一个元素开头的非递减的数组
如果,一个节点右边的元素,比当前值小,就删除右边的

答案

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode() {}
 * ListNode(int val) { this.val = val; }
 * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNodes(ListNode head) {
        ListNode newHead = iterationReverse(head);
        ListNode current = newHead;
        while (current.next != null) {
        	// 有小的就删除
            if (current.next.val < current.val) {
                current.next = current.next.next;
            } else {
                current = current.next;
            }
        }
        // 最后别忘了转回来
        return iterationReverse(newHead);
    }
	// 这个翻转比递归快
    private ListNode iterationReverse(ListNode head) {
        ListNode current = head, next = head;
        while (current != null && current.next != null) {
            next = current.next.next;
            current.next.next = head;
            head = current.next;
            current.next = next;
        }
        return head;
    }
}

待进行

138. 随机链表的复制
622. 设计循环队列
109. 有序链表转换二叉搜索树
460. LFU 缓存
355. 设计推特

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1572593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【智能算法应用】猎人猎物优化算法(HPO)在WSN覆盖中的应用

目录 1.算法原理2.数学模型3.结果展示4.参考文献 1.算法原理 【智能算法】猎人猎物算法&#xff08;HPO&#xff09;原理及实现 2.数学模型 3.结果展示 HPO设置区域边长为20&#xff0c;节点数为35&#xff0c;感知半径为2.5&#xff0c;实验结果如下&#xff1a; 4.参考…

iMazing 3 for Windows iOS设备管理软件2024最新功能解析

iMazing 3 for Windows是一款兼容Win和Mac的iOS设备管理软件。iMazing 3 for Windows能够将音乐、文件、消息和应用等数据从任何 iPhone、iPad 或 iPod 传输到 Mac 或 PC 上。 iMazing 3 win 版下载&#xff1a; https://souurl.cn/Qp6gFU iMazing 3 mac 版下载&#x…

一点点金融

一点点金融 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多趋势分析 改进MACD策略&#xff0c;使用涨跌幅比值RSI计算MACD原始MACD计算改进思路&#xff1a;使用涨跌幅比值RSI计算MACD 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多…

非关系型数据库——Redis基本操作

目录 一、Redis数据库常用命令 1.Set——存放数据 2.Get——获取数据 3.Keys——获取符合条件的键值 4.Exists——判断键值是否存在 5.Del——删除指定键值 6.Type——获取键值对应的类型 7.Rename——对已有键值重命名&#xff08;覆盖&#xff09; 8.Renamenx——对…

安全性基础知识

根据希赛相关视频课程汇总整理而成&#xff0c;个人笔记&#xff0c;仅供参考。本章核心为网络攻击和信息安全的实现技术 安全性基本概念 计算机安全原则&#xff1a; 在系统设计时&#xff0c;实现安全措施应具有简洁性&#xff1b; 系统的保护机制应该公开&#xff1b; 用户…

【Linux】使用cloudreve搭建个人网盘并传输文件

Cloudreve 是一个开源的个人网盘系统&#xff0c;能够帮助用户搭建属于自己的私有云存储服务。它支持多种存储后端&#xff0c;包括本地存储、远程FTP/SFTP存储、以及云存储服务如阿里云OSS、腾讯云COS和Amazon S3等。Cloudreve具有友好的用户界面和丰富的功能&#xff0c;比如…

Git相关的内容来这里看看吧

Git相关的内容来这里看看吧 1、Centos 安装Git方法一&#xff1a;yum命令安装(可能不是最新版本)方法二&#xff1a;源码安装Git配置以及如何配置密钥 Git常用命令参考链接 1、Centos 安装Git 方法一&#xff1a;yum命令安装(可能不是最新版本) yum install -y git卸载已安装…

虚拟机打不开

问题 另一个程序已锁定文件的一部分&#xff0c;进程无法访问 打不开磁盘“G:\centeros\hadoop104kl\hadoop100-cl2.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机。 原因 前一次非正常关闭虚拟机导致.lck 文件是VMWare软件的一种磁盘锁文件&…

计算机网络练习-计算机网络概述与性能指标

计算机网络概述 ----------------------------------------------------------------------------------------------------------------------------- 1. 计算机网络最据本的功能的是( )。 1,差错控制 Ⅱ.路由选择 Ⅲ,分布式处理 IV.传输控制 …

Tcl学习笔记(二)——表达式、字符串

目录 1. 表达式 算数操作符 关系操作符 逻辑操作符 按位操作符 选择操作符 数学函数 字符串操作 2. 字符串 字符串长度、大小写转换、裁剪、重复 字符串类型 字符的获取 字符串的添加、删除、替换 字符串的比较 字符串的简单搜索 字符串的匹配 格式化…

C语言中strlen函数的实现

C语言中strlen函数的实现 为了便于和strlen函数区别&#xff0c;以下命令为_strlen。 描述&#xff1a;实现strlen&#xff0c;获取字符串的长度&#xff0c;函数原型如下&#xff1a; size_t strlen(const char *str);_strlen实现&#xff1a; size_t _strlen(const char*…

开源流程图表库(04):mxGraph,都是可视化编辑,导出使用。

mxGraph是一个用于创建和展示图形的JavaScript库。它提供了丰富的功能和工具&#xff0c;可以用于构建各种类型的图形应用程序&#xff0c;包括流程图、组织结构图、网络拓扑图等。 mxGraph的编辑器 一、mxGraph的特点和功能 以下是一些mxGraph的特点和功能&#xff1a; 强大…

微信小程序的页面交互2

一、自定义属性 &#xff08;1&#xff09;定义&#xff1a; 微信小程序中的自定义属性实际上是由data-前缀加上一个自定义属性名组成。 &#xff08;2&#xff09;如何获取自定义属性的值&#xff1f; 用到target或currentTarget对象的dataset属性可以获取数据 &#xff…

dm8 备份与恢复

dm8 备份与恢复 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 设置bak_path路径 --创建备份文件存放目录 su - dmdba mkdir -p /dm8/backup--修改dm.ini 文件…

小米汽车su7全色系展示源码

源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 安装教程 纯HTML&#xff0c;直接将压缩包上传网站目录解压即可 首页截图 源码下载 小米汽车su7全色系展示源码-小8源码屋源码简介 小米汽车全色系展示源码&#xff0c;小米汽车su7全色系展示源码 …

从永远到永远-Git中tag的使用

Git中tag的使用 1.tag的作用2.使用背景3.tag的使用1.种类2.创建标签3.查看标签3.推送标签4. 删除标签: 4.idea可视化操作1.创建标签2.推送标签 999 删除、指定commit、验证暂时不表 1.tag的作用 Tag(标签)用来记录某个特定的提交(commit)。一个 Tag 被用来标记重要的历史节点&…

MOS管用作开关管时,工作在哪个区?

MOS管作为开关管使用时&#xff0c;主要工作在两个区域&#xff1a;截止区和饱和区&#xff0c;有时也会通过线性区。 截止区&#xff1a; 当MOS管的栅极-源极电压&#xff08;Vgs&#xff09;低于阈值电压&#xff08;Vth&#xff09;时&#xff0c;MOS管处于截止状态。在这种…

企业如何设计和实施有效的网络安全演练?

现实世界中&#xff0c;武装部队一直利用兵棋推演进行实战化训练&#xff0c;为潜在的军事冲突做准备。随着当今的数字化转型&#xff0c;同样的概念正在以网络安全演习的形式在组织中得到应用&#xff0c;很多企业每年都会基于合理的网络攻击场景和事件响应做一些测试和模拟。…

FaaF:利用事实作为评估RAG的函数方法

原文地址&#xff1a;faaf-facts-as-a-function-for-evaluating-rag 2024 年 4 月 5 日 在某些情况下&#xff0c;我们使用其他语言模型来验证RAG的输出结果&#xff0c;但这种方法并未能有效识别出数据生成过程中的错误和缺失。 论文解析 挑战 评估的可靠性和效率&#xff…

Cisco Packet Tracer配置AAA认证

出口路由器R1配置&#xff1a; ip domain-name cisco.com;写入设备的默认域名 crypto key generate rsa;产生rsa密钥 ip ssh secret cisco;启用ssh服务 enable secret cisco;设置特权模式密码 连接TACAS的路由器做同样配置 RADIUS服务器的配置 client ip 配置成RADIUS服务器…