常见算法题(也有自己 leetCode 刷的一些题,不断更新)
链表和数组的区别是什么?插入和查询的时间复杂度分别是多少?
- 链表和数组都是一个有序的集合,数组需要连续的内存空间,而链表不需要
- 链表的插入删除的时间复杂度是
O(1)
,数组是O(n)
- 根据下标查询的时间复杂度数组是
O(1)
,链表是O(n)
- 根据值查询的时间复杂度,链表和数组都是
O(n)
哈希表是如何实现的?如何解决地址冲突?
- 哈希表是也是通过数组来实现的,首先对key值进行哈希化得到一个整数,然后对整数进行计算,得到一个数组中的下标,然后进行存取
- 解决地址冲突常用方法有开放定址法和链表法
runtime
源码的存放weak
指针哈希表使用的就是开放定址法,Java
里的HashMap
使用的是链表法
如何检测链表中是否有环?
// 快慢指针法
class ListNode {
var next :ListNode?
var val :Int = 0
init(_ val:Int) {
self.val = val
self.next = nil
}
}
extension ListNode{
func haveCycle()->Bool{
var fast = self.next
var slow:ListNode? = self
while fast != nil {
if fast === slow{
return true
}
slow = slow?.next
fast = fast?.next?.next
}
return false
}
}
//调用
let node = ListNode(2)
let node1 = ListNode(3)
let node2 = ListNode(4)
let node3 = ListNode(5)
node.next = node1
node1.next = node2
node2.next = node3
node3.next = node2
print(node.haveCycle())
删除链表的节点
func deleteNode(_ head: ListNode?, _ val: Int) -> ListNode? {
if head?.val == val{
return head?.next;
}
let node:ListNode? = ListNode(0)
node?.next = head
var currentNode:ListNode? = node?.next
var preNode:ListNode? = node
while currentNode != nil{
if currentNode?.val == val{
preNode?.next = currentNode?.next
}
preNode = currentNode
currentNode = currentNode?.next
}
return node?.next
}
反转链表
func reverseList(_ head: ListNode?) -> ListNode? {
return reList(nil, head)
}
func reList(_ pre:ListNode?,_ cur:ListNode?)->ListNode?{
guard let _cur = cur else {
return pre
}
let res = reList(_cur, _cur.next)
_cur.next = pre
return res
}
从尾到头打印链表
func reversePrint(_ head: ListNode?) -> [Int] {
guard head != nil else {
return [Int]()
}
var arr = [Int]()
var ahead = head
while ahead != nil {
arr.append(ahead!.val)
ahead = ahead?.next
}
return arr.reversed()
}
反转二叉树
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init(_ val: Int) {
self.val = val
self.left = nil
self.right = nil
}
}
@discardableResult
func invertTree(_ root: TreeNode?) -> TreeNode? {
guard let root = root else{
return nil
}
let temp = root.left
root.left = root.right
root.right = temp
invertTree(root.left)
invertTree(root.right)
return root
}
验证两个二叉树是完全相等的嘛
func isSameTree(_ p: TreeNode?, _ q: TreeNode?) -> Bool {
guard let pNode = p ,let qNode = q else { return q == nil && p == nil }
return pNode.val == qNode.val && isSameTree(pNode.left, qNode.left) && isSameTree(pNode.right, qNode.right)
}
斐波拉契数列
//剑指 Offer 10- I. 斐波那契数列
func fib(_ n: Int) -> Int {
guard n > 1 else {
return n
}
var first = 0
var second = 1
for _ in 0..<n-1 {
let temp = first
first = second
second = temp + second
second %= 1000000007//答案需要取模 1e9+7(1000000007)
}
return second
}
反转字符串
func reverseString(_ s: inout [Character]) {
guard s.count > 1 else {
return
}
var i = 0
var j = s.count - 1
while i<j {
let temp = s[i]
s[i] = s[j]
s[j] = temp
i += 1
j -= 1
}
}
合并两个有序数组
func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
var mr = m - 1
var nr = n - 1
while nr >= 0 {
if mr >= 0 && nums1[mr] > nums2[nr]{
nums1[mr + nr + 1] = nums1[mr]
mr -= 1
} else {
nums1[mr + nr + 1] = nums2[nr]
nr -= 1
}
}
}