链表


  • [1、判断一个单链表是否有环]
    可使用一快一慢两个指针,一个指针每次走一步,另一个指针一次走两步。若存在环,若干步后,快的指针会赶上慢的指针。否则则判定不存在环
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}
static ListNode hasCircle(ListNode node) {
        if (node == null)
            return null;
        ListNode resultNode = null;
        ListNode slow = node.next;
        if (slow == null)
            return null;
        ListNode fast = slow.next;
        while (fast != null && slow != null) {
            if (fast == slow) {
                resultNode = fast;
                break;
            }
            slow = slow.next;
            fast = fast.next;
            if (fast != null) {
                fast = fast.next;
            }
        }
        return resultNode ;
    }
  • [2判断一个单链表中环的入口节点]
    首先使用1中方法判断链表中是否有环,获取环中任意一个节点,然后得到环的长度为n。
    然后定义两个指针,一个指针先走n步,然后两个指针在以相同的速度移动,当第二个指针走到入口节点时,第一个指针刚好走了一圈,也到达入口节点,这时就找到了环的入口节点。
static ListNode getEntryNode(ListNode node) {
        ListNode meetingNode = hasCircle(node);
        if (meetingNode == null)
            return null;
        int loopNum = 1;
        ListNode pNode1 = meetingNode;
        while (pNode1.next != meetingNode) {
            pNode1 = pNode1.next;
            ++loopNum;
        }
        pNode1 = node;
        for (int i = 0; i < loopNum; i++) {
            pNode1 = pNode1.next;
        }
        ListNode pNode2 = node;
        while (pNode1 != pNode2) {
            pNode1 = pNode1.next;
            pNode2 = pNode2.next;
        }
        return pNode1;
    }
      //返回头指针
    static ListNode insertNode(ListNode node, int k, int num) {
        ListNode kNode = new ListNode(num);
        if (node == null)
            node = new ListNode(num);
        int i = 0;
        ListNode preNode = node;
        while (preNode != null && i < k - 1) {
            if (++i == k - 1)
                break;
            preNode = preNode.next;
        }
        if ((k - 1) != i) {// 插入位置不合法
            return node;
        }
        if (k == 1) {// 插入首位
            kNode.next = node;
            node = kNode;
        } else {
            // 中间节点或尾结点
            kNode.next = preNode.next;
            preNode.next = kNode;
        }
        return node;
    }
  • 4找到单链表中的倒数第k个位置的结点
    设链表长为n,从后往前查第k个结点即从前往后找的第n-k+1个结点。这时可以使用两个指针,第一个指针先走k-1步,第k步时,两个指针同时往前走,因为两个指针始终相差k-1,所以当第一个指针到达链表终点时,第二个指针刚好到达n-k+1个结点,即倒数第k个结点。
    static ListNode getKNode(ListNode node, int k) {
        ListNode pHead = node;
        ListNode pBehind = node;
        for (int i = 0; i < k - 1; i++) {
            pHead = pHead.next;
        }
        while (pHead.next != null) {
            pHead = pHead.next;
            pBehind = pBehind.next;
        }
        return pBehind;
    }
  • 5链表逆置
public static ListNode reverseNode(ListNode node) {
        if (node == null)
            return null;
        ListNode reverseNode = null;
        ListNode head = node;
        ListNode preNode = null;
        while (head != null) {
            ListNode nextNode = head.next;
            if (nextNode == null)
                reverseNode = head;
            head.next = preNode;
            preNode = head;
            head = nextNode;
        }
        return reverseNode;
    }
public static ListNode delete(ListNode node, int data) {
        if (node == null)
            return null;
                //现将链表头部的值为data的数据删除
        while (node != null) {
            if (node.val == data)
                node = node.next;
            else   break;
        }
        ListNode preNode = null;//要删除的节点的前一个结点
        ListNode temp = node;//返回链表,先指向头结点
        ListNode head = node;//遍历指针
        while (head != null) {
            if (head.val != data) {
                preNode = head;
            } else {
                preNode.next = preNode.next.next;
            }
                        head = head.next;
        }
        return temp;
    }
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode node = new ListNode(0) , temp = node;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                temp.next = l1;
                l1 = l1.next;
            } else {
                temp.next=l2;
                l2 = l2.next;
            }
            temp = temp.next;
        }
        temp.next = (l1!=null)?l1:l2;   //若l1为null,则temp指向l2,否者指向l1
        return node.next;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容