单链表Node节点类

public class Node {

    public int val;
public Node next; public Node(int val) {
this.val = val;
}
}

  双链表DoubleNode类

public class DoubleNode {

    public int val;
public DoubleNode last;
public DoubleNode next; public DoubleNode(int val) {
this.val = val;
}
}

  

  一、打印两个有序链表的公共部分

  问题:给定两个有序链表head1和head2,打印两个链表的公共部分

  解答:(1)如果head1的值小于head2,则head1向下移动。(2)如果head2的值小于head1的值,则head2向下移动。(3)如果head1的值等于head2的值,则打印这个值,然后head1和head2都往下移动。(4)head1或head2有任意一个移动到null,则整个过程停止

    public void printCommonPart(Node head1, Node head2) {
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
head1 = head1.next;
} else if (head1.val > head2.val) {
head2 = head2.next;
} else {
System.out.print(head1.val + " ");
head1 = head1.next;
head2 = head2.next;
}
}
System.out.println();
}

打印两个有序链表的公共部分

  

  二、在单链表和双链表中删除倒数第K个节点

  题目1:删除单链表中倒数第K个节点

  在删除问题中,如果想要删除某一个节点,就必须定位到要删除节点的前一个节点。

  解答:

  (1)如果链表为空或者K值小于1,则直接返回即可。否则让链表从头开始走到尾,每移动一步,就让K值减1,链表走到结尾时,判断K值的大小

  (2)如果K值大于0(1→2→3,K=4,K:3 2 1),说明链表没有倒数第K个节点,直接返回即可。

  (3)如果K值等于0(1→2→3,K=3,K:2 1 0),说明倒数第K个节点就是头节点,直接删除头节点,返回head.next即可

  (4)如果K值小于0(1→2→3,K=2,K:1 0 -1),此时,重新从头节点开始走,每移动一步,就让K的值加1,当K等于0时,移动停止,此时的节点就是要删除节点的前一个节点。(假设链表长度为N,那么倒数第K个节点的前一个节点就是第N-K个节点,第一次遍历后,K变为K-N,第二次遍历后,遍历到第N-K个节点时K为0)

    public Node removeLastKthNode(Node head, int lastKth) {
if (head == null || lastKth < 1) {
return head;
}
Node cur = head;
while (cur != null) {
lastKth--;
cur = cur.next;
}
if (lastKth == 0) {
head = head.next;
}
if (lastKth < 0) {
cur = head;
while (++lastKth != 0) {
cur = cur.next;
}
cur.next = cur.next.next;
}
return head;
}

删除单链表中倒数第K个节点

  题目2:删除双链表中倒数第K个节点(和单链表同理,只是注意last指针的重连即可)

    public DoubleNode removeLastKthNode(DoubleNode head, int lastKth) {
if (head == null || lastKth < 1) {
return head;
}
DoubleNode cur = head;
while (cur != null) {
lastKth--;
cur = cur.next;
}
if (lastKth == 0) {
head = head.next;
head.last = null;
}
if (lastKth < 0) {
cur = head;
while (++lastKth != 0) {
cur = cur.next;
}
DoubleNode newNext = cur.next.next;
cur.next = newNext;
if (newNext != null) {
newNext.last = cur;
}
}
return head;
}

删除双链表中倒数第K个节点

  

  三、删除链表的中间节点和a/b处的节点

  题目1:删除链表的中间节点,例如1→2删除节点1,1→2→3删除节点2,1→2→3→4删除节点2,1→2→3→4→5删除节点3

  解答:如果链表为空或长度为1,则直接返回,如果链表长度为2,删除头节点即可,则3-2,4-2,5-3,6-3...,也就是长度每增加2,要删除的节点就后移一个节点。

    public Node removeMidNode(Node head) {
if (head == null || head.next == null) {
return head;
}
if (head.next.next == null) {
return head.next;
}
Node pre = head;
Node cur = head.next.next;
while (cur.next != null && cur.next.next != null) {
pre = pre.next;
cur = cur.next.next;
}
pre.next = pre.next.next;
return head;
}

删除链表的中间节点

  题目2:删除位于a/b处节点,链表1→2→3→4→5,假设a/b=r,则r==0不删除任何节点,r在(0,1/5]上删除节点1,r在(1/5,2/5]删除节点2,如果r大于1,不删除任何节点

  解答:根据链表长度n,以及a和b先计算出n*(a/b)的值,然后r向上取整就是要删除的节点的位置。

    public Node removeByRatio(Node head, int a, int b) {
if (a < 1 || a > b) {
return head;
}
int n = 0;
Node cur = head;
while (cur != null) {
n++;
cur = cur.next;
}
n = (int)Math.ceil((double) (a * n) / (double)b);
if (n == 1) {
head = head.next;
}
if (n > 1) {
cur = head;
while (--n != 1) {
cur = cur.next;
}
cur.next = cur.next.next;
}
return head;
}

删除单链表中a/b处的节点

  四、反转单向和双向链表

  题目1:反转单向链表

    public Node reverseList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}

反转单链表

  题目2:反转双向链表

    public DoubleNode reverseList(DoubleNode head) {
DoubleNode pre = null;
DoubleNode next = null;
while (head != null) {
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}

反转双向链表

  五、反转部分单向链表

  题目:给定一个单链表和两个整数from和to,把第from个到第to个节点这一部分进行反转。例如1→2→3→4→5→null,from=2,to=4,则1→4→3→2→5→null

  解答:

  (1)如果1<=from<=to<=N不满足,返回原来的头节点

  (2)找到第from-1个节点fPre和第to+1个节点tPos,把反转的部分先反转,然后正确连接fPre和tPos

  (3)如果fPre为null,说明反转部分是包含头节点的,返回每反转以前反转部分的最后一个节点作为新的头节点,如果fPre不为null,返回旧的头节点。

    public Node reversePart(Node head, int from, int to) {
int len = 0;
Node node1 = head;
Node fPre = null;
Node tPos = null;
while (node1 != null) {
len++;
fPre = len == from - 1 ? node1 : fPre;
tPos = len == to + 1 ? node1 : tPos;
node1 = node1.next;
}
if (from > to || from < 1 || to > len) {
return head;
}
node1 = fPre == null ? head : fPre.next;
Node node2 = node1.next;
node1.next = tPos;
Node next = null;
while (node2 != tPos) {
next = node2.next;
node2.next = node1;
node1 = node2;
node2 = next;
}
if (fPre != null) {
fPre.next = node1;
return head;
}
return node1;
}

反转部分单向链表

  六、两个单链表生成相加链表

  问题:9→3→7代表整数937,6→3代表整数63,将两个链表相加得到937+63=1000,返回1→0→0→0

  思路:如果先分别算出各自链表所代表的整数,那么链表的长度很长,可以表示一个很大的数,转换成int时可能会异常

  解法1:利用栈结构

  (1)将两个链表从左到右遍历,并压入各自的栈中。因此s1:9 3 7,s2:6 3,

  (2)将s1和s2同步弹出,然后相加链表即可,同时还需要关注是否有进位  

  (3)当s1和s2都为空时,如果进位信息为1,还要生成一个节点值为1的新结点

   注意:两个整数相加与进位问题。1. n1 = s1.isEmpty() ? 0 : s1.pop();2.n = n1 + n2 + ca;3.node = new Node(n % 10);4.ca = n / 10;

   注意:从后往前生成链表的过程。 pre = node; node = new Node(n % 10); node.next = pre;

    public Node addLists1(Node head1, Node head2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
while (head1 != null) {
s1.push(head1.val);
head1 = head1.next;
}
while (head2 != null) {
s2.push(head2.val);
head2 = head2.next;
}
int ca = 0;
int n1 = 0, n2 = 0;
int n = 0;
Node node = null;
Node pre = null;
while (!s1.isEmpty() || !s2.isEmpty()) {
n1 = s1.isEmpty() ? 0 : s1.pop();
n2 = s2.isEmpty() ? 0 : s2.pop();
n = n1 + n2 + ca;
pre = node;
node = new Node(n % 10);
node.next = pre;
ca = n / 10;
}
if (ca == 1) {
pre = node;
node = new Node(1);
node.next = pre;
}
return node;
}

  解法2:利用链表的逆序

  (1)将两个链表逆序,依次得到从低位到高位的数字

  (2)遍历两个逆序后的链表,过程和解法1类似

  需要注意:1.1 = c1 != null ? c1.val : 0; 2.c1 = c1 != null ? c1.next : null; 3.完成后还需要reverseList(head1); reverseList(head2);将原来的链表返回原状。

    public Node addList2(Node head1, Node head2) {
head1 = reverseList(head1);
head2 = reverseList(head2);
int ca = 0, n1 = 0, n2 = 0, n = 0;
Node c1 = head1;
Node c2 = head2;
Node node = null;
Node pre = null;
while (c1 != null || c2 != null) {
n1 = c1 != null ? c1.val : 0;
n2 = c2 != null ? c2.val : 0;
n = n1 + n2 + ca;
pre = node;
node = new Node(n%10);
node.next = pre;
ca = n / 10;
c1 = c1 != null ? c1.next : null;
c2 = c2 != null ? c2.next : null;
}
if (ca == 1) {
pre = node;
node = new Node(1);
node.next = pre;
}
reverseList(head1);
reverseList(head2);
return node;
}

利用链表的逆序

  七、删除无序单链表中值重复出现的节点

  问题:给定一个无序单链表,删除其中值重复出现的节点,例如1→2→3→3→4→4→2→1→1→null,返回1→2→3→4→null。

  解法1:利用哈希表,但是时间复杂度为O(N),空间复杂度为O(N)

  最近一个没有被删除的节点为pre,当前节点cur的值如果出现过,就令pre.next=cur.next;如果没出现过,就将cur的值加入到哈希表,同时令pre=cur。

    public void removeRep1(Node head) {
if (head == null) {
return;
}
HashSet<Integer> set = new HashSet<>();
Node pre = head;
Node cur = head.next;
set.add(head.val);
while (cur != null) {
if (set.contains(cur.val)) {
pre.next = cur.next;
} else {
set.add(cur.val);
pre = cur;
}
cur = cur.next;
}
}

删除无序单链表中重复节点

  解法2:利用选择排序的过程,时间复杂度为O(N2),空间复杂度为O(1)(直接选择排序时间复杂度为O(N2))

  例如1→2→3→3→4→4→2→1→1→null,(1)cur值为1,检查后面所有值为1的节点全部删除(2)cur值为2,检查后面值为2的节点全部删除...依次类推

    public void removeRep2(Node head) {
Node cur = head;
Node pre = null;
Node next = null;
while(cur != null) {
pre = cur;
next = cur.next;
while (next != null) {
if (cur.val == next.val) {
pre.next = next.next;
} else {
pre = next;
}
next = next.next;
}
cur = cur.next;
}

直接选择排序思想删除重复节点

  八、在单链表删除指定值的节点

  题目:给定一个单链表和一个整数num,删除值为num的全部节点。例如:1→2→3→4→null,num=3,返回:1→2→4→null

  方法1:O(N)+O(N)利用栈或者其他容器收集值不等于num的节点,收集完成后重新连接即可。最后返回栈底节点为新的头结点

    public Node removeValue1(Node head, int num) {
Stack<Node> stack = new Stack<>();
while(head != null) {
if (head.val != num) {
stack.push(head);
}
head = head.next;
}
while (!stack.isEmpty()) {
stack.peek().next = head; // head一开始为null
head = stack.pop();
}
return head;
}

利用栈删除单链表中指定值

  方法2:O(N)+O(1)不用任何容器直接调整。找到第一个不为num的节点作为新的头结点newHead,继续往后遍历,如果cur的值等于num,就将cur删除,即令最近一个值不等于num的pre.next=cur.next,如果不等于,就令pre=cur

    public Node removeValue2(Node head, int num) {
while (head != null) {
if (head.val != num) {
break;
}
head = head.next;
}
Node pre = head;
Node cur = head;
while(cur != null) {
if (cur.val == num) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}

直接调整法删除单链表中指定值

  

  九、单链表的选择排序

  题目:给定一个无序单链表,实现单链表的选择排序,要求空间复杂度为O(1)

  选择排序就是:从未排序的部分中找到最小值,然后放在排好序部分的尾部,逐渐将未排序的部分缩小,最后全部变成排好序的部分。

  解法:O(N2)+O(1)

  (1)找到最小值节点,将其设置成新的头节点newHead

  (2)每次在未排序的部分中找到最小值的节点,然后把这个节点从未排序的链表中删除,同时连接删除节点的前后节点

  (3)把删除的节点连接在排好序部分的链表尾部

    public Node getSmallestPreNode(Node head) {
Node smallPre = null;
Node small = head;
Node pre = head;
Node cur = head.next;
while (cur != null) {
if (cur.val < small.val) {
smallPre = pre;
small = cur;
}
pre = cur;
cur = cur.next;
}
return smallPre;// 返回以head为头结点的单链表中最小值节点的前一个节点
} public Node selectionSort(Node head) {
Node tail = null; // 已排序部分尾部
Node cur = head; // 未排序部分头部
Node smallPre = null; // 最小节点的前一个节点
Node small = null; // 值最小的节点
while (cur != null) {
small = cur;
smallPre = getSmallestPreNode(cur);
if (smallPre != null) {
// small为未排序部分的最小值
small = smallPre.next;
// 将最小值节点从未排序的部分删除
smallPre.next = small.next;
}
// smallPre为null时,说明当前节点cur已经是最小值,因此在原链表中删除头节点
cur = cur == small ? cur.next : cur;
if (tail == null) {
head = small;
} else {
tail.next = small;
}
tail = small;
}
return head;
}

  十、一种怪异的节点删除方式

  问题:给定一个链表的节点node,但不给定整个整个链表的头节点,如何在链表中删除node?并分析出现的问题

  思路:例如1→2→3→null,如果要删除节点2,那么在仅给定节点2的情况下,将节点2的值变成3,然后删除结点3即可。(在链表中删除节点的原则,必须定位到待删节点的上一个节点)

  可能出现的问题:

  (1)无法删除最后一个节点。因为如果要删除节点3,由于根本没有下一个节点来代替节点3被删除,那么只有让节点2的next指向null这一种办法,但是又根本找不到节点2,所以就无法正确删除节点3。

  (2)这种删除方式在本质上根本不是删除了node节点,而是把node节点的值改变,然后删除node的下一个节点。在实际工程中,一个节点可能代表很复杂的结构,节点的复制会相当复杂,或者可能改变节点值这个操作都是被禁止的;或者工程上一节点代表提供服务的一个服务器,外界对每个节点都有很多依赖,例如,在删除节点2时,实际上影响了节点3对外提供的服务。

  注意:异常的抛出,RuntimeException异常类不需要导包。

    public void removeNodeWired(Node node) {
if (node == null) {
return;
}
Node next = node.next;
if (next == null) {
throw new RuntimeException("can not remove last node.");
}
node.val = next.val;
node.next = next.next;
}

  十一、向有序的环形单链表中插入新节点

  问题:一个环形单链表从头节点head开始不降序,同时由最后的节点指向头节点。给定一个环形单链表的头节点和一个整数num,生成节点值为num的新节点,并插入到这个环形链表中,保证调整后的链表依然有序。

  解法:

  (1)生成节点值为num的新节点,记为node

  (2)如果链表为空,直接返回node

  (3)令pre=head,cur=head.next,令pre和cur同步移动,如果pre的节点值小于或等于num,并且cur的节点值大于或等于num,说明node应该在pre和cur节点之间插入

  (4)如果pre和cur转了一圈都没有发现插入位置,说明node应该插入到头节点的前面,此时是因为链表中每个节点都大于num或者都小于num。如果num比每个节点值都大,返回原来的头节点即可;如果num比每个节点的值都小,应该把node作为链表新的头节点返回。

    public Node insertNum(Node head, int num) {
Node node = new Node(num);
if (head == null) {
node.next = node;
return node;
}
Node pre = head;
Node cur = head.next;
while (cur != head) {
if (pre.val <= num && cur.val >= num) {
break;
}
pre = cur;
cur = cur.next;
}
pre.next = node;
node.next = cur;
return head.val < num ? head : node;
}

向有序的环形单链表中插入节点

  

  十二、合并两个有序的单链表

  题目:给定两个有序单链表head1和head2,返回合并后的链表。例如:0→2→3→7→null,1→3→5→7→9→null,返回0→1→2→3→3→5→7→7→9→null

  解法:(O(M+N) + O(1))

  (1)如果两个链表有一个为空,返回非空链表头节点

  (2)head1和head2中小的节点就是新链表的头节点

  (3)每次比较遍历到的值,根据大小关系作出调整,同时用一个变量pre表示上次比较时值较小的节点

链表1:1→5→6→null, 链表2:2→3→7→null
cur1=1,cur2=2,pre=null,cur1小于cur2,不作调整,pre=cur1
cur1=5,cur2=2,pre=1,cur2小于cur1,pre.next指向cur2,cur2.next指向cur1,pre=2,此时1→2→5→6→null,3→7→null,
cur1=5,cur2=3,pre=2,cur2小于cur1,pre.next指向cur2,cur2.next指向cur1,pre=3,此时1→2→3→5→6→null,7→null
cur1=5,cur2=7,pre=3,cur1小于cur2,不作调整,pre=5
cur1=6,cur2=7,pre=5,cur1小于cur2,不作调整,pre=6,
此时cur1=null,pre为链表1的最后一个节点,把pre.next指向cur2

  (4)如果链表1先走完,此时cur1=null,pre为链表1的最后一个节点,那么就把pre的next指针指向链表2的当前节点,即cur2;如果链表2先走完,说明链表2的所有节点已经插入到链表1中,此时返回新的头节点即可。

  注意:pre这个变量在这道题里面所起到的作用。 pre.next = cur1 == null ? cur2 : cur1;

    public Node merge(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return head1 != null ? head1 : head2;
}
Node head = head1.val < head2.val ? head1 : head2;
Node cur1 = head == head1 ? head1 : head2;
Node cur2 = head == head1 ? head2 : head1;
Node pre = null;
Node next = null;
while (cur1 != null && cur2 != null) {
if (cur1.val <= cur2.val) {
pre = cur1;
cur1 = cur1.next;
} else {
next = cur2.next;
pre.next = cur2;
cur2.next = cur1;
pre = cur2;
cur2 = next;
}
}
pre.next = cur1 == null ? cur2 : cur1;
return head;
}

  十三、按照左右半区的方式重新组合单链表

  问题:给定一个长度为N的单链表,如果N为偶数,那么前N/2个节点为左半区,后N/2个节点为右半区;如果N为奇数,那么前N/2个节点算作左半区,后N/2+1个节点为右半区,将单链表调整成L1→R1→L2→R2..的形式。例如:1→2→3→4→null调整为1→3→2→4→null,1→2→3→4→5→null调整为1→3→2→4→5→null

  解法:O(N)+O(1)

  (1)如果链表为空或长度为1,则直接返回

  (2)遍历一遍找到左半区的最后一个节点,记为mid,这里涉及到之前做过的题,求中间节点的方法:即从长度为2开始,长度每增加2,mid就向后移动一个节点。例如:12mid为1,123mid为1,1234mid为2,12345mid为2,123456mid为3...

  (3)将左右半区分离成2个链表即mid.next=null,头结点分别为原来的head记为left,和mid.next记为right。

  注意:1.mergeLR方法是将right链表的每一个节点依次插入到left的合适位置中。

     2.求链表中间节点mid的方法: Node mid = head; Node right = head.next; while (right.next != null && right.next.next != null) { mid = mid.next; right = right.next.next; }

    public void relocate(Node head) {
if (head == null || head.next == null) {
return;
}
Node mid = head;
Node right = head.next;
while (right.next != null && right.next.next != null) {
mid = mid.next;
right = right.next.next;
}
right = mid.next;
mid.next = null;
mergeLR(head, right);
} public void mergeLR(Node left, Node right) {
Node next = null;
while (left.next != null) {
next = right.next;
right.next = left.next;
left.next = right;
left = right.next;
right = next;
}
left.next = right;
}

OptimalSolution(3)--链表问题(1)简单的更多相关文章

  1. 单链表数据结构 - java简单实现

    链表中最简单的一种是单向链表,每个元素包含两个域,值域和指针域,我们把这样的元素称之为节点.每个节点的指针域内有一个指针,指向下一个节点,而最后一个节点则指向一个空值.如图就是一个单向链表 一个单向链 ...

  2. C链表之创建简单静态链表

    C代码: #include<stdio.h> #include<stdlib.h> #include<malloc.h> //创建简单静态链表 typedef st ...

  3. C 封装一个通用链表 和 一个简单字符串开发库

    引言 这里需要分享的是一个 简单字符串库和 链表的基库,代码也许用到特定技巧.有时候回想一下, 如果我读书的时候有人告诉我这些关于C开发的积淀, 那么会走的多直啊.刚参加工作的时候做桌面开发, 服务是 ...

  4. OptimalSolution(3)--链表问题(2)进阶

    一.环形单链表的约瑟夫问题 二.判断一个链表是否为回文结构 三.将单向链表按某只划分成左边小.中间相等.右边大的形式 四.复制含有随机指针节点的链表 五.两个单链表相交的一系列问题 六.将单链表的每K ...

  5. C语言实现简单的单向链表(创建、插入、删除)及等效STL实现代码

    实现个算法,懒得手写链表,于是用C++的forward_list,没有next()方法感觉很不好使,比如一个对单向链表的最简单功能要求: input: 1 2 5 3 4 output: 1-> ...

  6. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

  7. 链表反转leetcode206

    最近准备结束自己的科研生涯,准备要开始找工作了,准备在LEETCODE刷刷题...刷的前40题全部用python刷的,各种调包速度奇快,后被师哥告知这样没意义,于是准备开始回归C++,Python用的 ...

  8. javascript实现数据结构:线性表--线性链表(链式存储结构)

    上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...

  9. 深入分析 Linux 内核链表--转

    引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...

随机推荐

  1. Java中Synchronized的优化原理

    我们知道,从 JDK1.6 开始,Java 对 Synchronized 同步锁做了充分的优化,甚至在某些场景下,它的性能已经超越了 Lock 同步锁.那么就让我们来看看,它究竟是如何优化的. 原本的 ...

  2. gitbook 入门教程之小白都能看懂的 Gitbook 插件开发全流程

    什么是插件 Gitbook 插件是扩展 GitBook 功能(电子书和网站)的最佳方式. 只要是 Gitbook 默认没有提供的功能,基于插件机制都可以自行扩展,是插件让 Gitbook 变得更加强大 ...

  3. SOFAJRaft—初次使用

    SOFAJRaft-初次使用 SOFAJRaft 是基于 Raft 算法的生产级高性能 Java 实现,支持 MULTI-RAFT-GROUP.应用场景有 Leader 选举.分布式锁服务.高可靠的元 ...

  4. Linux下mysql相关操作

    Linux下mysql相关操作 1.创建MySQL mysql -u root -p create user 'username'@'%' identified by 'password'; %可以选 ...

  5. Java面试----01.JavaSE

    1.面向对象和面向过程的区别 面向过程:面向过程性能比面向对象高. 因为类调用时需要实例化,比较消耗资源,所以当性能是最重要的考虑因素时,比如单片机.嵌入式开发.Linux/Unix等一般采用面向对象 ...

  6. java第3天:Scanner,Random,ArrayList

    第一章:Scanner从入门到放弃 1 API的概述和使用步骤 API简称应用程序编程接口,是JDK给我们提供好的可以直接使用的类和方法,是程序员随手使用的字典. *** 2 Scanner的概述 2 ...

  7. Linux简单检查服务运行脚本

    脚本内容如下: 此脚本含义:检查服务是否运行,在运行则记录日志,不在运行则记录日志并将服务启动 #!/bin/bash svrnm="tomcat" //设置服务名称time=`d ...

  8. 非后端开发Mysql日常使用小结

    数据库的五个概念 数据库服务器 数据库 数据表 数据字段 数据行 那么这里下面既是对上面几个概念进行基本的日常操作. 数据库引擎使用 这里仅仅只介绍常用的两种引擎,而InnoDB是从MySQL 5.6 ...

  9. centos7升级openssl、openssh常见问题及解决方法

    升级至openssl 1.1.1版本 升级至openssh 8.0版本 openssl version -a   当前查看版本 一.安装telnet (以防升级失败,连不上服务器,建议弄) #查看是否 ...

  10. Failure to transfer org.springframework:spring-jcl:jar:5.0.7.RELEASE from

    错误信息: Failure to transfer org.springframework.boot:spring-boot-maven-plugin:pom:1.5.4.RELEASE from h ...