用js实现数据结构的简单方法

例1:找出单向链表中的一个节点,该节点到尾指针的距离为K。链表的倒数第0个结点为链表的尾指针。要求时间复杂度为O(n)。
链表节点的值初始化为1,2,3,4,5,6,7

function LinkFun(){//自定义链表的方法
    let Node = function(val){
        this.val = val;
        this.next = null
    }
    let head = null;
    let length = 0;
    this.append = function(val){//向链表添加节点以及数据的方法
        let node = new Node(val);
        let cur ;
        if(head == null){//第一次进入这个方法,head为空,
            head = node
        }else{//第二次以后调用这个方法,进当前的判断
            cur = head;
            while(cur.next){
                cur = cur.next
            }
            cur.next =node
        }
        length ++
    }
    this.getHead = function(){
        return head
    }
    this.getLength = function(){
        return length
    }
}
let arr = [];
for(let i = 1;i<8;i++){
    arr.push(i)
}
let link = new LinkFun();
for(let i = 0;i<7;i++){
    link.append(arr[i])
}
 
let head = link.getHead()
function getNode(head){
    let arr = [],pNode = head;
    while(pNode){
        arr.unshift( pNode.val )
        pNode = pNode.next
    }
    return arr
}
let res = getNode(head)
let n = readline()
print(res[n-1])

例2:已知输入一个链表,求该链表中的倒数第k个节点
(1)方法一:可以遍历链表然后将它存入数组,然后查询就可以了,实现过程就如同上一题的getNode()方法。
(2)方法二:可以用栈。遍历链表,然后将节点一次压入栈中,最后根据k,依次弹出,弹出的次数等于k,那么当前这个节点就是倒数第k个。

private ListNode sol1(ListNode head, int k) {
        Stack<ListNode> stack = new Stack<>();
        while (head != null) {
            stack.push(head);
            head = head.next;
        }
        if (stack.size() < k) {
            return null;
        }
        while (k > 1) {
            stack.pop();
            k--;
        }
        return stack.pop();
    }

(3)方法三:定义两个快慢指针。
以快指针走到null停下为例:
快指针停在null,慢指针刚好停在倒数第K个结点。
此时就它两的距离是K,所以我们设置慢指针开始走的条件应该是快指针走了K步之后。第K+1步的时候,快慢指针一起走。

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        //初始化两个指针
        ListNode fast,slow;
        fast= head;
        slow= head;
        //用于统计快指针走的步数
        int i = 0;
        //当快指针指向null时,停止循环
        while(fast != null){
            //当i大等k时,目标指针开始走
            /*这个判断写在最前面,逻辑会清晰点:
              不会漏掉对i=0时fast 、slow都指向head时,slow能不能走的判断*/
            if(i >= k){
                slow= slow.next;
            }
            //快指针指向下一个结点
            fast = fast .next;
            //i加一
            i++;
        }
        //如果i小于k,说明输入了k大于总结点数,返回null
        if(i < k){return null;}
        //否则返回目标结点
        return slow;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值