leetcode链表相关的题

10 篇文章 0 订阅

总结一下最近做过的链表相关的题目(后续不定时更新内容)
1、反转链表

本题使用指针反转,其他的方法:可以先遍历head,把数据保存到数组中,数组反转,然后定义一个新指针类遍历复制即可。

1->2->3->4->5反转输出为:5->4->3->2->1

function ReverseList(pHead){
    let pre = null;
    let curr = pHead;
    while(curr) {
        const next = curr.next;
        curr.next = pre;
        pre = curr;
        curr = next;
    }
    return pre;
}

2、删除链表中重复的数据(一)

1->1->2->3 删除后:1->2->3

function delete(head) {
	if (head === null) return null;
	    let cur = head;
	    while(cur.next) {//注意
	        if (cur.val === cur.next.val) {
	            cur.next = cur.next.next; //重点
	        } else {
	            cur = cur.next;
	        }
	    }
	 return head;
 }

3、删除链表中的重复的数据(二)

1->1->1->2->3->3->4->5 结果为:2->4->5
一般链表在做删除操作时,要定义一个pre的指针,next指向当前的指针cur

function deleteDuplication(pHead){
    if (pHead === null) return null;
   // let node = new ListNode(0, pHead); 第一种
    let node = null; node.next = pHead;
    let pre = node;
    let cur = pHead;
    while(cur) {
        if (cur.next && cur.val === cur.next.val) {
            cur = cur.next;//if已经相同了,,先移动一下
            // 判断cur是否等于下一个值,如果是,一直判断
            while(cur.next && cur.val === cur.next.val) {
                cur = cur.next;
            }
            cur = cur.next; //让指针指到下一个元素,比如:cur循环出来是最后一个1,因为结果不需要1,所以要指向下一个元素2
            pre.next = cur; //前一个指针的next指向当前不重复的值
        } else {
            pre =cur;
            cur = cur.next;
        }
    }
    return node.next;
}

4、删除链表中和指定元素相同的值

1->2->3->4->5, k = 4 结果为: 1->2->3->5
默认相同的值只有一个
function deleteNode(head, val) {
    if (head === null) return null;
    if (head.val === val) return head.next; //如果删除的是第一个节点
    let pre = null; //指向上一个节点,删除时使用
    let curr = head;
    while(curr) {
        if (curr.val === val) {
            pre.next = curr.next;
            return head; //如果删除多个重复的,可以替换为:curr = curr.next; return null -> return head
        } else { //移动指针
            pre = curr;
            curr = curr.next;
        }
    }
    return null;
}

5、删除链表中倒数第k个元素

2->5->1->9->3,k=2 结果为:2->5->1->3

var removeNthFromEnd = function(head, n) {
    if (!head) return null;
    let count = 0;
    let cur = head;
    while(cur) {//先遍历一遍,保存链表长度
        count++;
        cur = cur.next;
    }
    if (count - n === 0) return head.next; //如果是第一个元素的话,直接返回
    let i = 0;//用来计数
    let curr = head;
    let pre = null;
    while(curr) {
        if (i === count - n) {
            pre.next = curr.next;
            return head;
        }
        i++;
        pre = curr;
        curr = curr.next;
    }
    return head;
};

6、链表是否有环

判断链表是否有环,这里使用快慢指针;也可以使用map保存起来,,遍历的时候看看是否在集合中存在

var hasCycle = function(head) {
	if (!head || !head.next) return false;
    let slow = head;
    let fast = head.next.next;
    while(fast && fast.next) {
        if (slow === fast) return true;
        slow = slow.next;
        fast = fast.next.next;
    }
    return false;
};

7、链表中环的入口节点

function EntryNodeOfLoop(pHead){
    let map = new Map(); //使用集合保存每个值
    while(pHead) {
        const val = pHead.val;
        if (map.has(val)) {//判断是否存在过
            return val; 
        }
        map.set(val, val);
        pHead = pHead.next;
    }
    return null;
}

8、判断两个链表是否相交

和上题的思路差不多,都是利用集合保存
两种解法:
1、判断两个链表的最后一个元素是否相等(各自循环查看)
2、集合保存值,查看是否存在过

var getIntersectionNode = function(headA, headB) {
    const set = new Set();
    let A = headA;
    let B = headB;
    while(A) {
        set.add(A);
        A = A.next;
    }
    while(B) {
        if (set.has(B)) {
            return B
        }
        B = B.next;
    }
    return null;
};

…后面陆续添加。。。

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 java开发 的学习思路及方向。从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。

由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的 点击我的Gitee获取
还有 高级java全套视频教程 java进阶架构师 视频+资料+代码+面试题!

全方面的java进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值