单链表基础操作题记录

每次做算法基础练习就意识到自己有多笨,还是做一下笔记,时常看一看,能开拓一下思路,希望能积少成多。

  1. 链表原地反转:
    思路: 边遍历,边反向改next指针
    1. pre -> current -> next
    2. pre <- current next
    3. 将 pre 赋值为 current, current 赋值为 next, next 赋值为next.next ,相当于整体后移一位。
    4. 重复 2的操作,每次反向改一次next指向。
class Node : NSObject {
    
    var value : NSObject;
    var next : Node?;
    init(value:NSObject) {
        self.value = value;
    }
    
}

//链表原地反转
func reverse(head : Node?) {
    
    if (head == nil || head?.next==nil) {
        return;
    }
    
    var pre : Node? = nil;
    var current :Node = head!;
    var next : Node? = head!.next!;
    
    while head!.next != nil {
        current.next = pre;
        pre = current;
        current = next!;
        next = current.next;
    }

}

2.链表成环判断
/*
如果链表成环,只能是O型环,或者6形状环。 如果是O型的环,一个指针p站在原地不动,一个指针q出去跑一圈,一定等遇到q,但如果是6形状的环,前种方法就不行了。因此,p和q就都要出去跑圈,如果,让q跑快一点,p跑慢一点,如果链表成环的话,无论是O型状的,还是6型状的,q肯定会在某个时间节点,比q多跑一圈,而追上p,及p和q从header出发后,首次相遇。
*/

func hasCircle(head : Node?) -> Bool {
    
    if (head == nil || head?.next == nil) {return false};
    
    var current : Node? = head;
    var another : Node? = head!.next;
    while current?.next != nil {
        if current! === another! {
            return true;
        } else {
            current = current?.next;
            another = another?.next?.next;//让一个点跑快一点。。。。
        }
    }
    
    return false;
}

//链表相交
/*
链表的相交,一定是Y型相交,既然是Y型相交,必定有相同的trail,如果有相通的trail,则相交。相交后找交点 ,遍历两个链表的同时,记录长度,max链表长-min链表长 = n,长链表和短链表一起向下找相同元素,长链表从第n个节点开始,找到第一个相同的节点。

*/

func findSameNode (head1:Node?, head2:Node?) -> Node? {
    if head1 == nil || head2 == nil {return nil}
    
    var length1 : Int = 1;
    var length2 : Int = 1;

    var p : Node = head1!;
    var q : Node = head2!;
    
    while p.next != nil || q.next != nil {
        if (p.next != nil) {
            length1 += 1;
            p = p.next!;
        }
        
        if (q.next != nil) {
            length2 += 1;
            q = q.next!;
        }
    }
    
    if (p === q) {
        //有共同的尾部
        let sub : Int = abs(length1 - length2);
        
        var maxList : Node = length1>length2 ? head1! : head2!;
        var minList : Node = length1>length2 ? head2! : head1!;
        for _ in 1...sub {
            maxList = maxList.next!;
        }
        
        for _ in 1...max(length2, length1) {
            
            if (maxList === minList) {
                return maxList;
            } else {
                if maxList.next != nil && minList.next != nil {
                    maxList = maxList.next!;
                    minList = minList.next!;
                } else {
                    return nil;
                }
               
            }
        }
        
    } else {
        //没有共同的尾部,没有相交
        return nil;
    }
    
    return nil;
}

//给定链表的头指针和一个节点指针,在O(1)时间删除该节点
/*
主要思想都是「狸猫换太子」 将给定节点的值改为,该节点next的值,将该节点next指针设为next的next节点。

*/

//求链表倒数第k个节点
/* 题目描述:输入一个单向链表,输出该链表中倒数第k个节点,链表的倒数第0个节点为链表的尾指针。

分析:设置两个指针 p1、p2,首先 p1 和 p2 都指向 head,然后 p2 向前走 k 步,这样 p1 和 p2 之间就间隔 k 个节点,最后 p1 和 p2 同时向前移动,直至 p2 走到链表末尾。
*/

//求链表的中间节点,要求时间复杂度是O(n),遍历不得超过一次。

/*
受上面一题的启发,应该也可以只用两个指针同时遍历列表,如果指针p,指针q,同时从起点出发,如果q的速度是p的2倍的时候,那么当q到达终点的时候,p刚好才走到全程的一半。

及 q在遍历时每次走两步,q = q.next.next ,p走一步,p = p.next
*/

//找到环的入口点
//输入一个单向链表,判断链表是否有环。如果链表存在环,如何找到环的入口点?

/*
又是环的问题,环的问题一般都可转化到数学里的,同向运动的相遇问题,p,和q,同时出发,如果q比p跑得快,那么总有一时间点,q会比p跑一圈而相遇。那么可以设p的速度是1⃣️,q的速度是2⃣️,在遍历链表的过程中记录p走过的路程,及节点数n,q走过的路程及是2n。 此时可以得处环状的长度是n。得到环的长度后,可以进入第二步,找环的入口。

让p,q都回到链表的初始位置,q先行n步,然后,p,q同时以1⃣️的速度向下一个节点移动,直到,p和q相遇,此时p,q所处的位置即环的入口。
*/

//8. 扩展:链表有环,如何判断相交
//题目描述:上面的问题都是针对链表无环的,那么如果现在,链表是有环的呢?上面的方法还同样有效么?

/*
此时可以设想一下,如果两个链表相交,且两个链表相交,那么两个链表一定共同一个环。那么第一步,按照上述方法,假设链表A,B
1⃣️:利用p,q指针找到链表A的环入口 E1,和环的长度n。由于A和B同环,B的环长也是n,记录链表A的全长。

2⃣️:让p,q同时都在B链表的head处,让q先行n步,若在N步,然后p,q同时,同速度向后移近,在p,q相遇前,若q能等于E1,那么A、B链表相交于环部。否则,p,q,相遇时,记录链表B的长度。进入第3⃣️步

3⃣️:计算链表A,B的长度差 X,让p,q分别从A,B链表的head出发,长链表的指针先行X步,然后p,q同时移动,在p到达E1点前,如果p==q,那么AB相交于环外节点,否则无交点。
*/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容