链表笔试题总结——1

最近在复习数据结构,做了一些数据结构方面的笔试编程题,代码总结如下:

ps:下面的单链表默认都没有傀儡节点。

1、删除链表中等于给定值 val 的所有节点

 1     public ListNode removeElements(ListNode head, int val) {
 2         ListNode newhead = head;
 3         while (newhead != null && newhead.val == val) {
 4             newhead = newhead.next;
 5         }
 6         if (newhead == null)
 7             return null;
 8         ListNode front = newhead;
 9         ListNode last = newhead.next;
10         while (last != null) {
11             if (last.val == val) {
12                 front.next = last.next;
13                 last = last.next;
14             } else {
15                 front = last;
16                 last = last.next;
17             }
18         }
19         return newhead;
20     }

 

2、反转一个单链表

 1 public ListNode reverseList(ListNode head) {
 2     if (head == null) {
 3         return null;
 4     }
 5     ListNode newHead = head;
 6     ListNode tmp = head.next;
 7     head.next = null;
 8     while (tmp != null) {
 9         ListNode temp = tmp;
10         tmp = tmp.next;
11         temp.next = newHead;
12         newHead = temp;
13     }
14     return newHead;
15 }

 

3、求链表的中间节点

 1 public ListNode middleNode(ListNode head) {
 2     if (head == null) {
 3         return null;
 4     }
 5     if (head.next == null) {
 6         return head;
 7     }
 8     int length = 0;
 9     ListNode tmp = head;
10     while (tmp != null) {
11         length++;
12         tmp = tmp.next;
13     }
14     tmp = head;
15     for (int i = 0; i < length / 2; i++) {
16         tmp = tmp.next;
17     }
18     return tmp;
19 }

 

4、求倒数第k个链表

 1 public ListNode FindKthToTail(ListNode head, int k) {
 2     if (k == 0) {
 3         return null;
 4     }
 5     ListNode front = head;
 6     ListNode last = head;
 7     while (--k > 0 && last != null) {
 8         last = last.next;
 9     }
10     if (last == null) {
11         return null;
12     }
13     if (last.next == null && k == 0) {
14         return head;
15     }
16 
17     while (last.next != null) {
18         front = front.next;
19         last = last.next;
20     }
21     return front;
22 }

 

5、分割链表

 1 public ListNode partition(ListNode pHead, int x) {
 2     if (pHead == null) {
 3         return null;
 4     }
 5     ListNode newHead = null;
 6     ListNode tmp = pHead;
 7     ListNode temp = newHead;
 8     while (pHead != null) {
 9         if (pHead.val < x) {
10             if (newHead == null) {
11                 newHead = pHead;
12                 temp = newHead;
13             } else {
14                 temp.next = pHead;
15                 temp = temp.next;
16             }
17             pHead = pHead.next;
18             temp.next = null;
19         } else {
20             break;
21         }
22     }
23     if (pHead == null) {
24         return newHead;
25     }
26 
27     if (newHead == null) {
28         while (tmp.next != null && tmp.next.val >= x) {
29             tmp = tmp.next;
30         }
31         if (tmp.next == null) {
32             return pHead;
33         }
34         newHead = tmp.next;
35         tmp.next = tmp.next.next;
36         temp = newHead;
37         temp.next = null;
38     }
39 
40     tmp = pHead;
41     while (tmp.next != null) {
42         while (tmp.next != null && tmp.next.val >= x) {
43             tmp = tmp.next;
44         }
45         if (tmp.next == null) {
46             temp.next = pHead;
47         } else {
48             temp.next = tmp.next;
49             temp = temp.next;
50             tmp.next = tmp.next.next;
51             temp.next = null;
52         }
53     }
54 
55     temp.next = pHead;
56     return newHead;
57 }

 

6、去除链表重复节点,即1122234变成34

 1 public ListNode deleteDuplication(ListNode pHead) {
 2     if (pHead == null) {
 3         return null;
 4     }
 5     // 去除开头重复节点
 6     while (pHead.next != null && pHead.val == pHead.next.val) {
 7         int tmp = pHead.val;
 8         while (pHead != null && pHead.val == tmp) {
 9             pHead = pHead.next;
10         }
11         if (pHead == null) {
12             return null;
13         }
14     }
15     if (pHead.next == null) {
16         return pHead;
17     }
18     // 去除中间重复节点
19     boolean is = false;
20     ListNode node = pHead;
21     while (node.next != null) {
22         ListNode temp = node.next;
23         int tmp = temp.val;
24         while (temp.next != null && temp.next.val == temp.val) {
25             temp.next = temp.next.next;
26             is = true;
27         }
28         if (is) {
29             node.next = temp.next;
30             is = false;
31         } else {
32             node = node.next;
33         }
34     }
35     return pHead;
36 }

 

7、判断链表的回文结构

 1 public boolean chkPalindrome(ListNode A) {
 2     ArrayList<Integer> list = new ArrayList<>();
 3     ListNode cur = A;
 4     while (cur != null) {
 5         list.add(cur.val);
 6         cur = cur.next;
 7     }
 8     int length = list.size();
 9     int left = 0;
10     int right = length - 1;
11     while (left < right) {
12         if (!list.get(left).equals(list.get(right))) {
13             return false;
14         }
15         left++;
16         right--;
17     }
18     return true;
19 }

 

8、判断两个链表是否有交点,并返回第一个交点

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lengthA = 0;
        int lengthB = 0;
        ListNode tmpA = headA;
        ListNode tmpB = headB;
        while (tmpA != null) {
            lengthA++;
            tmpA = tmpA.next;
        }
        while (tmpB != null) {
            lengthB++;
            tmpB = tmpB.next;
        }
        tmpA = headA;
        tmpB = headB;
        if (lengthA > lengthB) {
            for (int i = 0; i < lengthA - lengthB; i++) {
                tmpA = tmpA.next;
            }
        } else {
            for (int i = 0; i < lengthB - lengthA; i++) {
                tmpB = tmpB.next;
            }
        }
        while (tmpA != null) {
            if (tmpA == tmpB) {
                return tmpA;
            }
            tmpA = tmpA.next;
            tmpB = tmpB.next;
        }
        return null;
    }

 

9、判断链表是否有环

 1 public boolean hasCycle(ListNode head) {
 2     ListNode slow = head;
 3     ListNode fast = head;
 4     while (fast != null && fast.next != null) {
 5         fast = fast.next.next;
 6         slow = slow.next;
 7         if (fast == slow) {
 8             return true;
 9         }
10     }
11     return false;
12 }

 

10、找链表的入环节点

 1 public ListNode detectCycle(ListNode head) {
 2     // 判断是否有环
 3     ListNode slow = head;
 4     ListNode fast = head;
 5     while (fast != null && fast.next != null) {
 6         slow = slow.next;
 7         fast = fast.next.next;
 8         if (fast == slow) {
 9             break;
10         }
11     }
12     if (fast == null || fast.next == null) {
13         return null;
14     }
15     // 找入环结点
16     slow = head;
17     while (slow != fast) {
18         slow = slow.next;
19         fast = fast.next;
20     }
21     return slow;
22 }

 

11、删除倒数第n个节点

 1 public ListNode removeNthFromEnd(ListNode head, int n) {
 2     ListNode fast = head;
 3     ListNode slow = head;
 4     int i = 0;
 5     for (; i < n && fast != null; i++) {
 6         fast = fast.next;
 7     }
 8     if (i == n) {
 9         if (fast == null) {
10             head = head.next;
11             return head;
12         } else {
13             while (fast.next != null) {
14                 slow = slow.next;
15                 fast = fast.next;
16             }
17             slow.next = slow.next.next;
18             return head;
19         }
20     }
21     return head;
22 }

 

12、合并k个有序链表

 1 public ListNode mergeKLists(ListNode[] lists) {
 2     int size = lists.length;
 3     if (size == 0) {
 4         return null;
 5     }
 6     if (size == 1) {
 7         return lists[0];
 8     }
 9     ListNode tt = lists[0];
10     for (int i = 1; i < size; i++) {
11         ListNode tmp = lists[i];
12         tt = lists[0];
13         // 合并两个链表
14         if (tt == null) {
15             lists[0] = tmp;
16             continue;
17         }
18         if (tmp == null) {
19             continue;
20         }
21         // 判断第一个结点的大小
22         if (tmp.val < lists[0].val) {
23             lists[0] = tmp;
24             tmp = tmp.next;
25             lists[0].next = tt;
26             tt = lists[0];
27         }
28         while (tt.next != null && tmp != null) {
29             if (tt.next.val >= tmp.val) { // 插入tmp
30                 ListNode t = tmp.next;
31                 tmp.next = tt.next;
32                 tt.next = tmp;
33                 tmp = t;
34                 tt = tt.next;
35             } else {
36                 tt = tt.next;
37             }
38         }
39         if (tt.next == null) {
40             tt.next = tmp;
41         }
42     }
43     return lists[0];
44 }

 

13、两两交换链表中的节点

 1 public ListNode swapPairs(ListNode head) {
 2     if (head == null) {
 3         return null;
 4     }
 5     if (head.next == null) {
 6         return head;
 7     }
 8     ListNode tmp = head; // 1
 9     ListNode front = head; // 1
10     head = head.next; // 2
11     tmp.next = head.next;// 1->3
12     head.next = tmp;// 2->1
13     tmp = front.next;// 3
14     while (tmp != null && tmp.next != null) {
15         ListNode t = tmp.next.next;// null
16         front.next = tmp.next;
17         tmp.next.next = tmp;
18         tmp.next = t;
19         front = tmp;
20         tmp = t;
21     }
22     return head;
23 }

 

14、旋转链表,顺时针旋转k个位置,即12345,旋转2个位置后变成45123

 1 public ListNode rotateRight(ListNode head, int k) {
 2     if (head == null) {
 3         return null;
 4     }
 5     if (head.next == null) {
 6         return head;
 7     }
 8     int length = 0;
 9     ListNode fast = head;
10     ListNode slow = head;
11     // 计算链表长度
12     while (fast != null) {
13         fast = fast.next;
14         length++;
15     }
16     int len = k % length; // 旋转长度
17     if (len == 0) {
18         return head;
19     }
20     fast = head;
21     for (int i = 0; i < len; i++) {
22         fast = fast.next;
23     }
24     while (fast.next != null) {
25         slow = slow.next;
26         fast = fast.next;
27     }
28     fast.next = head;
29     head = slow.next;
30     slow.next = null;
31     return head;
32 }

 

15、排序链表

 1 public ListNode sortList(ListNode head) {
 2     if (head == null || head.next == null) {
 3         return head;
 4     }
 5     ListNode tail = head;
 6     ListNode tmp = head;
 7     ListNode cur = head.next;
 8     while (cur != null) {
 9         tmp = head;
10         if (cur.val >= tail.val) { // 尾插
11             tail = cur;
12             cur = cur.next;
13             continue;
14         }
15         if (cur.val < head.val) { // 头插
16             tail.next = cur.next;
17             cur.next = head;
18             head = cur;
19             cur = tail.next;
20             continue;
21         }
22         while (tmp != tail && tmp.next.val < cur.val) {
23             tmp = tmp.next;
24         }
25         tail.next = cur.next;
26         cur.next = tmp.next;
27         tmp.next = cur;
28         cur = tail.next;
29     }
30     return head;
31 }

 

16、重排链表

 1 public void reorderList(ListNode head) {
 2     if (head == null || head.next == null || head.next.next == null) {
 3         return;
 4     }
 5     int length = 0;
 6     ListNode slow = head;
 7     ListNode fast = head;
 8     while (fast.next != null && fast.next.next != null) {
 9         slow = slow.next;
10         fast = fast.next.next;
11     }
12     ListNode lasthead = slow.next; // 指向后半部分链表【待逆置的链表】
13     slow.next = null;
14     // 逆置后半部分链表
15     fast = lasthead.next;
16     ListNode tmp = fast;
17     lasthead.next = null;
18     while (fast != null) {
19         tmp = fast.next;
20         fast.next = lasthead;
21         lasthead = fast;
22         fast = tmp;
23     }
24     // 合并两个链表
25     fast = lasthead.next;
26     slow = head;
27     while (lasthead != null && slow != null) {
28         fast = lasthead.next;
29         lasthead.next = slow.next;
30         slow.next = lasthead;
31         lasthead = fast;
32         slow = slow.next.next;
33     }
34 }

 

以上是部分链表编程题,后续我还会放置更多的编程题及其答案,上述代码有什么不对的地方或者可以优化的地方,欢迎大家指出~~

 

posted @ 2021-07-25 09:19  一帆小白  阅读(72)  评论(0编辑  收藏  举报