从尾到头打印链表
问题:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
思路:先将链表的值放到数组中,然后将数组中pop的值放到新的数组中。返回新数组。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {number[]}
*/
var reversePrint = function(head) {
let arr=[];
while(head!=null){
arr.push(head.val)
head=head.next
}
let newArr=[];
for(let i=0,len=arr.length;i<len;i++){
newArr.push(arr.pop())
}
return newArr
};
返回倒数第K个节点
问题:实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
思路:采用双指针,都从头节点开始,fast指针先走K步,然年两个指针一起每次走一步,直到快指针指向最后一个节点的下一个节点null,此时满指针就处在倒数第K个节点上。
/**
* @param {ListNode} head
* @param {number} k
* @return {number}
*/
var kthToLast = function(head, k) {
if(head==null) return head;
let fast=head;
let slow=head;
let n=k;
while(n){
fast=fast.next;
n--;
}
while(fast!=null){
slow=slow.next;
fast=fast.next;
}
return slow.val
};
环形链表
问题:给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
思路:给定快慢指针,分别从第一个节点及第二个节点出发,快指针没走两步,满指针走一步,若是环形链表,则总会相遇,最终判断一下是指针相遇还是没有下一个节点了。
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if(!head)return false;
let p=head;
let q=head.next;
while(p!=q&&q&&q.next){
p=p.next;
q=q.next.next;
}
return Boolean(q&&q.next)
};
K 个一组翻转链表
问题:给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
- 你可以设计一个只使用常数额外空间的算法来解决此问题吗?
- 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。(leetcode 25)
思路:每k个一组翻转,首先我们要判断下剩余节点数够不够翻转的,然后翻转该组,然后拼接该组的头到上一组的尾部。
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
//判断剩余节点是否剩余够k个
var canReverse=function(head,k){
let p=head;
let n=k;
while(--k&&p)p=p.next;
if(p==null)return head;
return reverseK(head,n)
}
// 翻转该组K个节点
var reverseK=function(head,k){
if(k==1)return head;
let tail=head.next;
let p=reverseK(head.next,k-1);
head.next=tail.next;
tail.next=head;
return p;
}
//拼接
var reverseKGroup = function(head, k) {
let virtur=new ListNode(0,head);//虚拟头节点
let p=virtur;
let q=p.next;//开始翻转的第一个节点
while((p.next=canReverse(q,k))!=q){//将上一组的尾节点连接到下一组的头节点,同时判断下本组是否够节点翻转。
p=q;//上一组的尾节点赋值
q=p.next;//下一组的头节点
}
return virtur.next //反转后第一个节点
};
只出现一次的数字
问题:给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。 请你找出并返回那个只出现了一次的元素。(leetcode 004)
思路:利用Map对象,创建一个哈希表,遍历哈希表中值即可得出。
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let map=new Map();
for(let i=0;i<nums.length;i++){
if(map.has(nums[i])){
let num=map.get(nums[i])
map.set(nums[i],num+1);
}else{
map.set(nums[i],1);
}
}
for(let [item,count] of map.entries()){
if(count==1){
return item;
}
}
};