数据结构与算法题之链表

  1. 两数相加
    描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头
    在这里插入图片描述

题解:

/**
 1. Definition for singly-linked list.
 2. public class ListNode {
 3.     int val;
 4.     ListNode next;
 5.     ListNode() {}
 6.     ListNode(int val) { this.val = val; }
 7.     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 8. }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        int carry = 0;
        while(l1 != null || l2 != null) {
            int x = l1 == null ? 0 : l1.val;
            int y = l2 == null ? 0 : l2.val;
            int sum = x + y + carry;
            
            carry = sum / 10;
            sum = sum % 10;
            cur.next = new ListNode(sum);

            cur = cur.next;
            if(l1 != null)
                l1 = l1.next;
            if(l2 != null)
                l2 = l2.next;
        }
        if(carry == 1) {
            cur.next = new ListNode(carry);
        }
        return pre.next;


    }
}

2. 删除链表的倒数第 N 个结点

描述:删除链表的倒数第 n 个结点,并且返回链表的头结点。
题解:

/**
 1. Definition for singly-linked list.
 2. public class ListNode {
 3.     int val;
 4.     ListNode next;
 5.     ListNode() {}
 6.     ListNode(int val) { this.val = val; }
 7.     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 8. }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode pre = new ListNode(0);
        pre.next = head;
        ListNode start = pre, end = pre;
        while(n != 0) {
            start = start.next;
            n--;
        }
        while(start.next != null) {
            start = start.next;
            end = end.next;
        }
        end.next = end.next.next;
        return pre.next;



    }
}

3. 合并两个有序链表
描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
在这里插入图片描述
题解:

/**
 1. Definition for singly-linked list.
 2. public class ListNode {
 3.     int val;
 4.     ListNode next;
 5.     ListNode() {}
 6.     ListNode(int val) { this.val = val; }
 7.     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 8. }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if(l1 == null) {
            return l2;
        }
        if(l2 == null) {
            return l1;
        }
        if(l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

4. 两两交换链表相邻的值
描述:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。不只是单纯的改变节点内部的值,而是需要实际的进行节点交换
题解:

/**
 1. Definition for singly-linked list.
 2. public class ListNode {
 3.     int val;
 4.     ListNode next;
 5.     ListNode() {}
 6.     ListNode(int val) { this.val = val; }
 7.     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 8. }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        //假设链表为1>2>3>4
        //定义新节点,存储第二个原节点2
        ListNode newHead = head.next;
        //头节点指向三四节点递归后的,即1>3>4
        head.next = swapPairs(newHead.next);
        //2指向头节点,即2>1>3>4
        newHead.next = head;
        return newHead;
    }
}

5. 旋转链表
描述:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
题解:

/**
 * 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 rotateRight(ListNode head, int k) {
        if(head == null || head.next == null || k==0) return head;
         //计算链表的长度,顺便得到链表的最后一个节点
        ListNode cur = head;
        int len = 1;
        while (cur.next != null) {
            len++;
            cur = cur.next;
        }
        //和第三种解法一样,对于k超过链表长度的问题,直接取模即可
        int index = len - (k % len) - 1;
        //最后一个节点指向头节点,形成环
        cur.next = head;
        //来到重新组装链表的位置
        for (int i = 0; i < index; i++) {
            head = head.next;
        }
        //head的next节点便是新的头节点,head自身便是尾节点
        ListNode newHead = head.next;
        //断开头尾节点
        head.next = null;
        return newHead;

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值