leetcode链表算法题实现思路

找出两个链表的交点(leetcode160)

  一条链表遍历完之后跳转到下一条链表的头节点继续遍历。

   因为当两条链表均被遍历一遍以后,第二次遍历时会同时到达节点相等的地方。如果没有相交的节点,两条链表均遍历两遍后,同时等于null,故返回null。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode l1 = headA, l2 = headB;
    while (l1 != l2) {
        l1 = (l1 == null) ? headB : l1.next;
        l2 = (l2 == null) ? headA : l2.next;
    }
    return l1;
}

链表反转(leetcode206)

  1、非递归

    新建一个头结点newHeadNode,将新头节点的next赋给旧头节点的next,然后将旧头节点赋给新头节点的next并继续迭代。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode newHeadNode = new ListNode(-1);
        while(head != null) {
            ListNode next = head.next;
            head.next = newHeadNode.next;
            newHeadNode.next = head;
            head = next;
        }
        return newHeadNode.next;
    }
}
//更简单的办法

class Solution {
    public ListNode reverseList(ListNode head) {       
    ListNode newHead = null;
      while (head != null) {
         ListNode nextNode = head.next;
         head.next = newHead;
         newHead = head;
         head = nextNode;
      }
      return newHead;
  } }
 

  2、递归

    进入递归直到head.next == null,然后回到上一层,此时newHeadNode是最后一个节点,head是倒数第二个节点。将最后一个节点的next指向倒数第二个节点,再将倒数第二个节点的next置空,以防止链表反转后最后一个节点的next不为null。依此类推反复执行head.next.next = head; head.next = null;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode newHeadNode = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHeadNode;
    }
}

归并两个有序链表(leetcoed21)

  1、递归

    比较两个链表的值的大小,若l1.val < l2.val则将l2向后迭代,直至l1或l2为null并返回另一个不为null的节点然后开始逐层拼接。

/**
 * 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) {
        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;
        }
    }
}

  2、非递归

    创建一个新的链表并将两条链表逐一添加到新链表中。

/**
 * 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 newHeadNode = new ListNode(-1);
        ListNode prev = newHeadNode;
        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                prev.next = l1;
                l1 = l1.next;
            }else{
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }
        prev.next = l1 == null ? l2 : l1;//添加最后一个节点
        return newHeadNode.next;
    }
}

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

  1、非递归

    判断当前链表节点的值与后一个链表的值是否相等,若相同,则将后一个节点的next指向当前节点的next。若不同,则向后迭代直至边界。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode current = head;
        while (current != null && current.next != null) {
          if (current.next.val == current.val) {
              current.next = current.next.next;
          } else {
              current = current.next;
          }
      }
      return head;
    }
}

  2、递归

    递归到最后一层开始返回,如果head.val == head.next.val 则一直返回最后一个节点,如果不同则开始拼接。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null)   return head;
        head.next = deleteDuplicates(head.next);
        return head.next.val == head.val ? head.next : head;
    }
}

删除链表的倒数第n个节点(leetcode19)

  1、两次循环

    先遍历获取链表长度,再遍历找到节点的前一个位置。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode curr = new ListNode(-1);
        curr.next = head;
        ListNode first = head;
        int length = 0;
        while(first != null) {
            first = first.next;
            length++;
        }
        length -= n;
        first = curr;
        while(length-- > 0) {
            first = first.next;
        }
        first.next = first.next.next;
        return curr.next;
    }
}

   2、一次循环

    创建两个节点一个指向head,一个指向距head节点 n 个节点的节点,即n+1个节点。当第n+1个节点为null时,指向head的节点刚好指向倒数第n个位置。

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode fast = head;
    while (n-- > 0) {
        fast = fast.next;
    }
    if (fast == null) return head.next;
    ListNode slow = head;
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }
    slow.next = slow.next.next;
    return head;
}

交换链表中的相邻结点(leetcode24)

  1、递归

    递归至尾节点,然后将最后一个节点的next指向head.next,head指向next.next。完成交换。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode next = head.next;
        head.next = swapPairs(next.next);
        next.next = head;
        return next;
    }
}

    2、非递归

    思路如上,从头开始俩俩交换。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode pre = new ListNode(0);
        pre.next = head;
        ListNode temp = pre;
        while(temp.next != null && temp.next.next != null) {
            ListNode start = temp.next;
            ListNode end = temp.next.next;
            temp.next = end;
            start.next = end.next;
            end.next = start;
            temp = start;
        }
        return pre.next;
    }
}

两数相加 II(leetcode445) 

  双栈法。即利用两个栈进行运算并拼接链表。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> stack1 = buildStack(l1);
        Stack<Integer> stack2 = buildStack(l2);
        ListNode head = new ListNode(-1);
        int carry = 0;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int x = stack1.isEmpty() ? 0 : stack1.pop();
            int y = stack2.isEmpty() ? 0 : stack2.pop();
            int sum = x + y + carry;
            ListNode node = new ListNode(sum % 10);
            node.next = head.next;
            head.next = node;
            carry = sum / 10;
        }
        return head.next;
    }

    private Stack<Integer> buildStack(ListNode l) {
        Stack<Integer> stack = new Stack<>();
        while (l != null) {
            stack.push(l.val);
            l = l.next;
        }
        return stack;
    }
}

回文链表(leetcode)

  找到中间点,分割,反转,比较。  

public boolean isPalindrome(ListNode head) {
    if (head == null || head.next == null) return true;
    ListNode slow = head, fast = head.next;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    if (fast != null) slow = slow.next;  // 偶数节点,让 slow 指向下一个节点
    cut(head, slow);                     // 切成两个链表
    return isEqual(head, reverse(slow));
}

private void cut(ListNode head, ListNode cutNode) {
    while (head.next != cutNode) {
        head = head.next;
    }
    head.next = null;
}

private ListNode reverse(ListNode head) {
    ListNode newHead = null;
    while (head != null) {
        ListNode nextNode = head.next;
        head.next = newHead;
        newHead = head;
        head = nextNode;
    }
    return newHead;
}

private boolean isEqual(ListNode l1, ListNode l2) {
    while (l1 != null && l2 != null) {
        if (l1.val != l2.val) return false;
        l1 = l1.next;
        l2 = l2.next;
    }
    return true;
}

分割链表(leetcode725)

  先遍历确定链表的长度,然后和k值进行运算比较确定每个分割链表的大小,最后进行遍历填充。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode[] splitListToParts(ListNode root, int k) {
        int N = 0;
        ListNode cur = root;
        while (cur != null) {
            N++;
            cur = cur.next;
        }
        int mod = N % k;
        int size = N / k;
        ListNode[] ret = new ListNode[k];
        cur = root;
        for (int i = 0; cur != null && i < k; i++) {
            ret[i] = cur;
            int curSize = size + (mod-- > 0 ? 1 : 0);
            for (int j = 0; j < curSize - 1; j++) {
                cur = cur.next;
            }
            ListNode next = cur.next;
            cur.next = null;
            cur = next;
        }
        return ret;
    }
}

奇偶链表(leetcode328)

  新建一个奇数位置的迭代指针odd和一个偶数位置迭代指针even,然后第一个.next = 第三个;第二个.next = 第四个;并向后迭代最后把偶数头部指向奇数末尾odd。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head == null) {
            return head;
        }
        ListNode odd = head, even = head.next, evenHead = even;
        while(even != null && even.next != null) {
            odd.next = odd.next.next;
            odd = odd.next;
            even.next = even.next.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }
}

 

原文地址:https://www.cnblogs.com/yrtx/p/11524008.html

时间: 2024-11-05 16:38:29

leetcode链表算法题实现思路的相关文章

LeetCode | HouseCode 算法题

题目: You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will a

链表算法题

单链表 function LinkedList() { //需要插入链表的元素 var Node = function(element) { this.element = element;//元素的值 this.next = null;//指向下一个节点项的指针 }; var length = 0;//链表的长度 var head = null;//链表中第一个节点(的引用) //向链表尾部追加元素 this.append = function(element) { var node = new

Leetcode链表算法

两数相加 难度:中等       类型: 链表 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和. 您可以假设除了数字 0 之外,这两个数都不会以 0 开头. 示例 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 解题思路 两个列表同时

[leetcode]经典算法题- String to Integer (atoi)

题目描述: 把字符串转化为整数值 原文描述: Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for

【leetcode】 算法题2 两数相加

问题 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807 代码实现 #include <vector> #include <map> #include <iostream>

算法题个人思路总结

1.设A与C是互质的两个数,求B,使得A*B=1(mod C). 解:由于gcd(A,C)=1,因此利用扩展欧几里德函数可以找到a*A+c*C=1,即a*A=1(mod C).我们取B=a即可. 2.求$\sum_{i=1}^n{\frac{1}{i}}$的上下界. 解:$\ln \left( n+1 \right) \le \int_1^{n+1}{\frac{1}{x}dx}\le \sum_{i=1}^n{\frac{1}{i}}\le 1+\int_1^n{\frac{1}{x}dx}=

反转链表算法题

反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶:你可以迭代或递归地反转链表.你能否用两种方法解决这道题? 解决方案 方法一:迭代 假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3. 在遍历列表时,将当前节点的 next 指针改为指向前一个元素.由于节点没有引用其上一个节点,因此必须事先存储其前一个元素.在更改引用之前,还需要另一个

【leetcode】 算法题3 无重复字符的最长子串

问题 给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1. 给定 "pwwkew" ,最长子串是 "wke" ,长度是3.请注意答案必须是一个子串,"pwke" 是 子序列  而不是子串 代码实现 class S

【算法题 14 LeetCode 147 链表的插入排序】

算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution(object): def insertionSortList(self, head): """ :type head: ListNode