-
1、算法一:删除重复的元素
///MARK: remove dulplicate ///给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 ///由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。 ///将最终结果插入 nums 的前 k 个位置后返回 k 。 ///不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 func removeDunplicate(array:[Int]){ let result = self.removeStartIndex(array: array) let removeStartIndex = result.1 let resultArray = result.0.prefix(removeStartIndex) print("remove dulplicate: original:\(array) result:\(resultArray)") } ///MARK: get start index of remove in array func removeStartIndex(array:[Int]) -> ([Int],Int){ guard array.count > 1 else{ print("数组个数小于2个") return (array,array.count) } var arr = array let count = arr.count var j = 0 for index in 1..<count{ if arr[index] != arr[j]{ j += 1 arr[j] = arr[index] } } return (arr,j + 1) }
-
2、算法二:盛最多水的容器
///给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 ///找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 ///返回容器可以储存的最大水量。 ///说明:你不能倾斜容器 func maxArea(array:[Int]){ if array.count < 2{ print("数据个数小于两个") return } var indexOne = 0 var indexTwo = 0 var area = 0 for index in 1..<array.count{ for inerIndex in 0..<index{ let width = index - inerIndex let height = (array[index] - array[inerIndex]) < 0 ? array[index] : array[inerIndex] let tempArea = width * height if tempArea > area{ area = tempArea indexOne = inerIndex indexTwo = index } } } print("indexOne:\(indexOne) indexTwo:\(indexTwo) area:\(area)") }
-
3、算法三:将0移动到末尾
///给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 ///必须在不复制数组的情况下原地对数组进行操作。 func moveZeros(arr:inout [Int]){ var zeroIndex = 0 var nonZeroIndex = 0 print("moveZeros:original:\(arr)") let count = arr.count while(zeroIndex<count-1 && nonZeroIndex<count-1){ while(zeroIndex<count && arr[zeroIndex] != 0){ if nonZeroIndex <= zeroIndex{ nonZeroIndex += 1 } zeroIndex += 1 } while(nonZeroIndex<count && arr[nonZeroIndex] == 0){ nonZeroIndex += 1 } if zeroIndex < count && nonZeroIndex < count{ arr[zeroIndex] = arr[nonZeroIndex] arr[nonZeroIndex] = 0 } zeroIndex += 1 nonZeroIndex += 1 } print("moveZeros:result:\(arr)") }
-
4、算法4:
///将两个升序链表合并为一个新的 升序 链表并返回。 ///新链表是通过拼接给定的两个链表的所有节点组成的。 func mergeTwoLists(_ list1:MergeNode?, _ list2:MergeNode?) -> MergeNode?{ if list1 == nil{ return list2 } if list2 == nil{ return list1 } var result = list1 var node1 = list1 var currNodeLast = list1 var node2 = list2 var tempNode2 : MergeNode? while(node2 != nil){ if node2!.value < node1?.value ?? 0{ if currNodeLast?.value != node1?.value{ currNodeLast?.next = node2 }else{ result = node2 } tempNode2 = node2?.next node2?.next = node1 currNodeLast = node2 node2 = tempNode2 }else{ currNodeLast = node1 node1 = node1?.next if node1 == nil{ currNodeLast?.next = node2 break } } } return result } class MergeNode : NSObject{ var value : Int = 0 var next : MergeNode? }
-
5、算法五:
///给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。 ///你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 func swapPairs(_ head:MergeNode?) -> MergeNode?{ var result = head var node1 = head var node2 = head?.next var tempNode : MergeNode? var isFirstExchange = true while(node1 != nil && node2 != nil){ if isFirstExchange{ result = node2 isFirstExchange = false } node1?.next = node2?.next node2?.next = node1 tempNode?.next = node2 tempNode = node1 node1 = node1?.next node2 = node1?.next } return result }
-
6、算法六:
///反转链表 func reverseLink(_ head:MergeNode?) -> MergeNode?{ if head == nil || head?.next == nil{ return head } var node1 = head var node2 = head?.next var node3 = node2?.next node2?.next = node1 node1?.next = nil if node3 == nil{ return node2 } while(node3 != nil){ node1 = node3 node3 = node3?.next node1?.next = node2 node2 = node1 } return node2 } ///给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。 ///k 是一个正整数,它的值小于或等于链表的长度。 ///如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 ///进阶: ///你可以设计一个只使用常数额外空间的算法来解决此问题吗? ///你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。 //移动节点的方式 func reverseKGroup(_ head:MergeNode?,_ k:Int) -> MergeNode?{ var node = head var groupFisrtNode = head var nextGroupFirstNode : MergeNode? var lastGroupEndNode : MergeNode? var groupCount = 1 var isFirstExchange = true var result = head while(node != nil){ if groupCount == k{ nextGroupFirstNode = node?.next node?.next = nil let reverseList = reverseLink(groupFisrtNode) if isFirstExchange{ result = reverseList isFirstExchange = false }else{ lastGroupEndNode?.next = reverseList } lastGroupEndNode = groupFisrtNode groupFisrtNode?.next = nextGroupFirstNode groupCount = 1 groupFisrtNode = nextGroupFirstNode node = nextGroupFirstNode }else{ node = node?.next groupCount += 1 } } return result }
-
7、算法七:
///给你一个链表的头节点 head ,判断链表中是否有环。 ///如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。 ///如果链表中存在环 ,则返回 true 。 否则,返回 false 。 ///使用龟兔赛跑赛跑的方式,龟:每次移动一个,兔:每次移动两个,最后如果兔子和龟相遇,说明会有循环 func hasCycle(_ head:MergeNode?) -> Bool{ var slow = head var fast = head?.next while(slow != nil){ if slow == fast{ return true } slow = slow?.next fast = fast?.next?.next } return false }
转载请标明出处