LeetCode-1-LinkList-Easy

基础差,不要再逃避算法了,开始刷leetcode,按照标签里的难度刷。
在这里插入图片描述
思路:
两个链表合并为一个链表的话,先创建一个新的链表 LinkNode dummy = new LinkNode(0),然后依次比较两个链表的数据,谁小就把谁放进新链表中。

//递归
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;
        }
    }
}
//迭代
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
         ListNode dummy = new ListNode(0);
        ListNode p = dummy;
        while ((l1 != null) && (l2 != null)){
            if (l1.val < l2.val){
                p.next = l1;
                l1 = l1.next;
            }
            else {
                p.next = l2;
                l2 = l2.next;
            }
            p = p.next;
        }
        if (l1 == null)
            p.next = l2;
        if (l2 == null)
            p.next = l1;
        return dummy.next;
        
    }

在这里插入图片描述

思路:
对于这种需要移动判断链表每一个节点的题,要创建一个游标节点ListNode p = head代替head头结点来移动判断,因为如果直接使用head的话往后移动前面的结点就会被jvm回收,然后通过游标结点p来移动判断下一个结点是否等于下下一个结点,如果相等的话,就让下一个结点指向下下一个节点。

//递归
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null)
            return head;   
        head.next = deleteDuplicates(head.next);
        if (head.val == head.next.val){
            head = head.next;
        }
        return head;
    }
}
//迭代
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode p = head;
        while (p != null && p.next != null){
            if (p.val == p.next.val){
                p.next = p.next.next;
            }
            else{
                p = p.next;
            }
        }
        return head;
    }
}

在这里插入图片描述

思路:
环形链表一般就是两个方法:第一个是创建HashSet,第二个是你追我赶。第一种方法:判断是否是环形链表就是看有没有重复结点,创建HashSet数据结构,HashSet继承了Set接口,里面不允许存储重复的数值,所以通过add()方法依次添加每一个结点,在添加前首先判断这个set集合里是否已经包含这个结点:contain()方法。第二种方法:创建一个慢结点和一个快结点,慢结点每次指向它的下一个结点,快结点每次指向它的下下个结点,这样如果链表是环形的,那么快结点总会到某一个时刻等于慢结点。就像环形跑道中速度快的人总会超过速度慢的人。

    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null)
            return false;
        
        ListNode slow = head;
        ListNode fast = head.next;
                
        while (slow != fast){
            if (fast == null || fast.next == null)
                return false;
            slow = slow.next;
            fast = fast.next.next;
        }
        
        return true;
        
    }


public boolean hasCycle(ListNode head) {
        Set<ListNode> s = new HashSet<>();
        while(head != null){
            if (s.contains(head))
                return true;
            else 
                s.add(head);
            head = head.next;
        }
        
        return false;

在这里插入图片描述思路:
这种属于判断两个不同长度的链表,创建两个游标结点,游标结点遍历完自己的链表后就直接指向另外一条链表,这样就相当于将两条链表拼成了一条链表。

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null)
            return null;
        ListNode a = headA;
        ListNode b = headB;
       
        while (a != b){
            a = a == null ? headB : a.next;
            b = b == null ? headA : b.next;
        }
        return a;
    }

在这里插入图片描述
思路:
首先要判断头结点的值是否等于给定值,然后在通过游标结点判断后续的值。

public ListNode removeElements(ListNode head, int val) {
        
        while (head != null && head.val == val){
            head = head.next;
        }
        
        ListNode prev = head;
        
        if (prev != null){
            
            while(prev.next != null){
                if (prev.next.val == val)
                    prev.next = prev.next.next;
                else
                    prev = prev.next;
            }
            
        }
        return head;
        
    }

数据结构说实话在代码实现上学的真的不好,我恨不得回到大二在小明的课上认真听代码写代码。现在直接做这些题说实话没有思路也不知道怎么着手,目前就是看看题想想,然后看看解析别人怎么写的,看懂了后自己写,写完五道题后就在空白文档再敲一遍,然后补充写上每道题的思路,暂时就这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值