双指针系列

141. 环形链表

给定一个链表,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false 。

 

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

 

示例 1:



输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

方法一 类似哈希表 用map也可
var hasCycle = function(head) {
    if(head == null || head.next == null){
        return false
    }
    var set = new Set();
    while(head!=null){
        if(set.has(head)){
            return true;
        }
        set.add(head)
        head=head.next;
    }
    return false
   
};
方法二 快慢指针法
var hasCycle = function(head) {
    if(head == null || head.next == null){
        return false
    }
    var slow = head;
    var fast = head.next;
    while(slow !=fast){
        if(fast ==null || fast.next ==null){
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
};

142. 环形链表 II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:

你是否可以使用 O(1) 空间解决此题?
 

示例 1:



输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
var detectCycle = function(head) {
    var slow = head;
    var fast = head;
    while(fast!=null&&fast.next!=null){
        slow=slow.next;
        fast=fast.next.next
        if(slow==fast){
            break
        }
    }
    if(fast==null||fast.next==null){
        return null
    }
    slow = head;
    while(slow!=fast){
        slow=slow.next;
        fast=fast.next;
    }
    return slow
};
方法二 哈希 如果遇到一样的节点,那么说明这就是环的入口节点
var detectCycle = function(head) {
     var set = new Set();
    while(head!=null){
        if(set.has(head)){
            return head;
        }
        set.add(head)
        head=head.next;
    }
    return null
};

19. 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

var removeNthFromEnd = function(head, n) {
    var slow = fast = head;
    while(n>0){
        fast=fast.next;
        n--;
    }
    if(fast==null){
        return head.next;
    }
    while(fast!=null && fast.next!=null){
        fast=fast.next;
        slow=slow.next;
    }
    slow.next=slow.next.next
    return head;
};

167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

 

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

var reverseString = function(s) {
    var left = 0;
    var right = s.length-1;
    while(left<right){
        var temp = s[left];
        s[left] = s[right];
        s[right] = temp;
        left++;
        right--;
    }
    return s;
};

206. 反转链表

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
//迭代法
var reverseList = function(head) {
    if(head==null||head.next==null){return head}
    var cur = head;
    var pre = null;
    while(cur!=null){
        var nextTmp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = nextTmp;
    }
    return pre;
};
//递归法
var reverseList = function(head) {
    if(head==null||head.next==null)return head;
    var last = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return last;
};
posted @ 2020-12-12 22:53  拉肥尔  阅读(54)  评论(0)    收藏  举报