数据结构和算法——链表

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

使用链表结构可以克服数组需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

删除链表中重复元素(排序链表)

思路:有序链表,遍历当前节点和下一个节点相等,删除即可

public ListNode deleteDuplicates(ListNode head) {
       ListNode list = head;
       while(list!=null){
         if(list.next==null){
         	break;
         }
         if(list.val == list.next.val){
         	list.next = list.next.next;
         }else{
         	list = list.next;
         }
       }
       return head;
    }
删除链表的倒数第N个节点
public ListNode removeNthFromEnd(ListNode head, int n) {
		ListNode start = new ListNode(0);
        ListNode slow = start, fast = start;
        slow.next=head;
        fast.next=head;
        //fast指针每次多走一步,n+1次多走n+1步
        for (int i = 1; i <= n + 1; i++) {
            fast = fast.next;
        }
        //找到第n+1个节点
        while (fast != null) {
            slow = slow.next;
            fast = fast.next;
        }
        //删除节点
        slow.next = slow.next.next;
        return start.next;
      }
    }
环形链表(给定一个链表,判断链表中是否有环)

思路:快慢指针,一定会相遇

public static boolean hasCycle(ListNode head) {
       if(head==null){
       		return false;
       }
       ListNode fast=head;
       ListNode slow=head;
       while(fast!=null && fast.next!=null){
       		fast=fast.next.next;
       		slow=slow.next;
       		if(slow==fast){
       			return true;
       		}
       }
    	return false;
    }
相交链表:找到两个单链表相交的起始节点

思路:1.消除长度,2.找相同节点

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
       int lenA = length(headA), lenB = length(headB);
       while(lenA > lenB){
           headA=headA.next;
           lenA--;
       }
        while(lenA < lenB){
           headB=headB.next;
           lenB--;
       }	
       while(headA!=headB){
           headA=headA.next;
           headB=headB.next;
       }
    	return headA;
    }

 private int length(ListNode node) {
        int length = 0;
        while (node != null) {
            node = node.next;
            length++;
        }
        return length;
    }
反转链表

思路:前置节点为NULL,遍历原链表,当前节点的next指向pre,重置pre节点和curr节点

 public ListNode reverseList(ListNode head) {
       ListNode curr = head,pre=null;
       while(curr!=null){
           ListNode next=curr.next;
           curr.next=pre;
           pre=curr;
           curr=next;
       }
     	return pre;
    }
回文链表

思路:使用快速和慢速指针查找列表的中间位置。这意味着当快速指针到达最后一个末尾时,慢速指针将到达中间,然后反转最后一半,并将列表前半部分中的每个元素与后半部分中的元素进行比较。

public boolean isPalindrome(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        if (fast != null) {
            slow = slow.next;
        }
        //后半部分
        slow = reverse(slow);
        while (slow != null && head.val == slow.val) {
            head = head.next;
            slow = slow.next;
        }
        return slow == null;
    }
链表的中间节点

思路:双指针

public ListNode middleNode(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
    		return slow;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值