算法与数据结构是程序员基本功,但是入门着实不易,在极客时间找了一门非常适合新手人们入门的课程,一遍学习一遍记录,方便日后查看。编程语言选用Swift,并针对技术点丰富了一些感想和随笔。
Github的算法Repo包括了所有的系列札记,同时还有本人刷leetcode、《剑指offer》的历程。如果你感兴趣,可以去看看。Go to Github
数组和链表
| 数据结构 | 时间复杂度 |
|---|---|
| 数组(顺序表) | O(1)的查找,O(n)的插入和删除 |
| 单链表 | O(n)的查找,O(1)的插入和删除 |
| 双链表 | O(n)的查找,O(1)的插入和删除,既有前驱节点又有后继节点 ,同上 |
Leetcode真题
206-翻转链表
//提供两种办法,分析题意需要一个哨兵节点记录链表的头部位置。
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
class Solution {
func reverseList(_ head: ListNode?) -> ListNode? {
guard let safeHead = head else {
return nil
}
var cur: ListNode = safeHead
var pre: ListNode? = nil
while(cur.next != nil) {
let curNext = cur.next!
cur.next = pre
pre = cur
cur = curNext
}
cur.next = pre
return cur
}
}
class Solution {
func reverseList(_ head: ListNode?) -> ListNode? {
guard let safeHead = head else {
return nil
}
var cur: ListNode? = safeHead
var pre: ListNode? = nil
while cur != nil {
let curNext: ListNode? = cur!.next
cur!.next = pre
pre = cur
cur = curNext
}
return pre
}
}
24-两两交换链表中的节点
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
class Solution {
func swapPairs(_ head: ListNode?) -> ListNode? {
guard let safeHead = head, safeHead.next != nil else {
return head
}
var secondNode = safeHead.next
var thirdNode = secondNode?.next
secondNode?.next = safeHead
safeHead.next = swapPairs(thirdNode)
return secondNode
}
}
class Solution {
func swapPairs(_ head: ListNode?) -> ListNode? {
guard let safeHead = head else {
return nil
}
let firstNode: ListNode = ListNode(0) //哨兵
var pre: ListNode = firstNode
pre.next = safeHead
while (pre.next != nil) && (pre.next?.next != nil) {
let a = pre.next!
let b = pre.next?.next!
let bnext = b?.next
pre.next = b
b?.next = a
a.next = bnext
pre = a //这个是重点
}
return firstNode.next
}
}
141-环形链表
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
//方法一,快慢指针。
func hasCycle(head: ListNode?) -> Bool {
guard let safeHead = head else {
return false
}
var slow = safeHead
var fast = safeHead
while slow.next != nil && fast.next?.next != nil {
slow = slow.next!
fast = (fast.next?.next)!
if slow === fast {
return true
}
}
return false
}
方法二,使用数据结构set。
func hasCycle(head: ListNode?) -> Bool {
guard let safeHead = head else {
return false
}
var set: Set<ListNode> = []
var cur: ListNode? = safeHead
while cur != nil {
if set.contains(cur!) {
return true
}
set.insert(cur!)
cur = cur!.next
}
return false
}
142- 环形链表 II
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
//检测到有环后,一个指针从头开始动,另外的指针接着之前判断环的地方动,那么两个指针相遇的位置就是第一次入环的位置啦。
func detectCycle(head: ListNode?) -> ListNode? {
guard let safeHead = head, safeHead.next != nil else {
return nil;
}
var slow = safeHead
var fast = safeHead
var hasCycle = false
while slow.next != nil && fast.next?.next != nil {
slow = slow.next!
fast = (fast.next?.next)!
if slow === fast {
hasCycle = true
break
}
}
if hasCycle {
var follower = safeHead
while follower !== slow {
follower = follower.next!
slow = slow.next!
}
return follower
}
本系列仅是个人学习笔记,并未包括所有教程内容,如有侵权请联系删除。 极客时间链接