diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index f8c9da5f..fd17af62 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -9,7 +9,7 @@ ## 1. 两数之和 -https://leetcode-cn.com/problems/two-sum/ +[力扣题目链接](https://leetcode-cn.com/problems/two-sum/) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 @@ -29,10 +29,10 @@ https://leetcode-cn.com/problems/two-sum/ 很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。 建议大家做这道题目之前,先做一下这两道 -* [242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA) -* [349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q) +* [242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html) +* [349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html) -[242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q)这道题目是通过set作为哈希表来解决哈希问题。 +[242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html)这道题目是通过set作为哈希表来解决哈希问题。 本题呢,则要使用map,那么来看一下使用数组和set来做哈希法的局限。 @@ -51,7 +51,7 @@ C++中map,有三种类型: std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。 -同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)。 +同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://www.programmercarl.com/哈希表理论基础.html)。 **这道题目中并不需要key有序,选择std::unordered_map 效率更高!** @@ -110,13 +110,14 @@ Python: ```python class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: - hashmap={} - for ind,num in enumerate(nums): - hashmap[num] = ind - for i,num in enumerate(nums): - j = hashmap.get(target - num) - if j is not None and i!=j: - return [i,j] + records = dict() + + # 用枚举更方便,就不需要通过索引再去取当前位置的值 + for idx, val in enumerate(nums): + if target - val not in records: + records[val] = idx + else: + return [records[target - val], idx] # 如果存在就返回字典记录索引和当前索引 ``` diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md index e46dae6d..6df8c83d 100644 --- a/problems/0059.螺旋矩阵II.md +++ b/problems/0059.螺旋矩阵II.md @@ -302,6 +302,61 @@ func generateMatrix(n int) [][]int { } ``` +Swift: + +```swift +func generateMatrix(_ n: Int) -> [[Int]] { + var result = [[Int]](repeating: [Int](repeating: 0, count: n), count: n) + + var startRow = 0 + var startColumn = 0 + var loopCount = n / 2 + let mid = n / 2 + var count = 1 + var offset = 1 + var row: Int + var column: Int + + while loopCount > 0 { + row = startRow + column = startColumn + + for c in column ..< startColumn + n - offset { + result[startRow][c] = count + count += 1 + column += 1 + } + + for r in row ..< startRow + n - offset { + result[r][column] = count + count += 1 + row += 1 + } + + for _ in startColumn ..< column { + result[row][column] = count + count += 1 + column -= 1 + } + + for _ in startRow ..< row { + result[row][column] = count + count += 1 + row -= 1 + } + + startRow += 1 + startColumn += 1 + offset += 2 + loopCount -= 1 + } + + if (n % 2) != 0 { + result[mid][mid] = count + } + return result +} +``` diff --git a/problems/0129.求根到叶子节点数字之和.md b/problems/0129.求根到叶子节点数字之和.md index b37270e2..17642793 100644 --- a/problems/0129.求根到叶子节点数字之和.md +++ b/problems/0129.求根到叶子节点数字之和.md @@ -165,7 +165,32 @@ public: Java: Python: +```python3 +class Solution: + def sumNumbers(self, root: TreeNode) -> int: + res = 0 + path = [] + def backtrace(root): + nonlocal res + if not root: return # 节点空则返回 + path.append(root.val) + if not root.left and not root.right: # 遇到了叶子节点 + res += get_sum(path) + if root.left: # 左子树不空 + backtrace(root.left) + if root.right: # 右子树不空 + backtrace(root.right) + path.pop() + def get_sum(arr): + s = 0 + for i in range(len(arr)): + s = s * 10 + arr[i] + return s + + backtrace(root) + return res +``` Go: JavaScript: diff --git a/problems/0143.重排链表.md b/problems/0143.重排链表.md index 62232051..76df63b7 100644 --- a/problems/0143.重排链表.md +++ b/problems/0143.重排链表.md @@ -222,7 +222,61 @@ public class ReorderList { ``` Python: +```python3 +# 方法二 双向队列 +class Solution: + def reorderList(self, head: ListNode) -> None: + """ + Do not return anything, modify head in-place instead. + """ + d = collections.deque() + tmp = head + while tmp.next: # 链表除了首元素全部加入双向队列 + d.append(tmp.next) + tmp = tmp.next + tmp = head + while len(d): # 一后一前加入链表 + tmp.next = d.pop() + tmp = tmp.next + if len(d): + tmp.next = d.popleft() + tmp = tmp.next + tmp.next = None # 尾部置空 + +# 方法三 反转链表 +class Solution: + def reorderList(self, head: ListNode) -> None: + if head == None or head.next == None: + return True + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + right = slow.next # 分割右半边 + slow.next = None # 切断 + right = self.reverseList(right) #反转右半边 + left = head + # 左半边一定比右半边长, 因此判断右半边即可 + while right: + curLeft = left.next + left.next = right + left = curLeft + curRight = right.next + right.next = left + right = curRight + + + def reverseList(self, head: ListNode) -> ListNode: + cur = head + pre = None + while(cur!=None): + temp = cur.next # 保存一下cur的下一个节点 + cur.next = pre # 反转 + pre = cur + cur = temp + return pre +``` Go: JavaScript: diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index 1c630b6a..2e784e6a 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -111,25 +111,29 @@ Python: ```python class Solution: def isHappy(self, n: int) -> bool: - set_ = set() - while 1: - sum_ = self.getSum(n) - if sum_ == 1: + def calculate_happy(num): + sum_ = 0 + + # 从个位开始依次取,平方求和 + while num: + sum_ += (num % 10) ** 2 + num = num // 10 + return sum_ + + # 记录中间结果 + record = set() + + while True: + n = calculate_happy(n) + if n == 1: return True - #如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false - if sum_ in set_: + + # 如果中间结果重复出现,说明陷入死循环了,该数不是快乐数 + if n in record: return False else: - set_.add(sum_) - n = sum_ - - #取数值各个位上的单数之和 - def getSum(self, n): - sum_ = 0 - while n > 0: - sum_ += (n%10) * (n%10) - n //= 10 - return sum_ + record.add(n) + ``` Go: diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index a2c6e90d..9235d47e 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -304,6 +304,34 @@ var removeElements = function(head, val) { }; ``` +Swift: + +```swift +/** + * Definition for singly-linked list. + * public class ListNode { + * public var val: Int + * public var next: ListNode? + * public init() { self.val = 0; self.next = nil; } + * public init(_ val: Int) { self.val = val; self.next = nil; } + * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; } + * } + */ +func removeElements(_ head: ListNode?, _ val: Int) -> ListNode? { + let dummyNode = ListNode() + dummyNode.next = head + var currentNode = dummyNode + while let curNext = currentNode.next { + if curNext.val == val { + currentNode.next = curNext.next + } else { + currentNode = curNext + } + } + return dummyNode.next +} +``` + diff --git a/problems/0234.回文链表.md b/problems/0234.回文链表.md index 6a24b1d0..b3ad899c 100644 --- a/problems/0234.回文链表.md +++ b/problems/0234.回文链表.md @@ -148,7 +148,62 @@ public: ## Python -```python +```python3 +#数组模拟 +class Solution: + def isPalindrome(self, head: ListNode) -> bool: + length = 0 + tmp = head + while tmp: #求链表长度 + length += 1 + tmp = tmp.next + + result = [0] * length + tmp = head + index = 0 + while tmp: #链表元素加入数组 + result[index] = tmp.val + index += 1 + tmp = tmp.next + + i, j = 0, length - 1 + while i < j: # 判断回文 + if result[i] != result[j]: + return False + i += 1 + j -= 1 + return True + +#反转后半部分链表 +class Solution: + def isPalindrome(self, head: ListNode) -> bool: + if head == None or head.next == None: + return True + slow, fast = head, head + while fast and fast.next: + pre = slow + slow = slow.next + fast = fast.next.next + + pre.next = None # 分割链表 + cur1 = head # 前半部分 + cur2 = self.reverseList(slow) # 反转后半部分,总链表长度如果是奇数,cur2比cur1多一个节点 + while cur1: + if cur1.val != cur2.val: + return False + cur1 = cur1.next + cur2 = cur2.next + return True + + def reverseList(self, head: ListNode) -> ListNode: + cur = head + pre = None + while(cur!=None): + temp = cur.next # 保存一下cur的下一个节点 + cur.next = pre # 反转 + pre = cur + cur = temp + return pre ``` ## Go diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 29c1c144..7489352d 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -121,13 +121,7 @@ Python: ```python class Solution: def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: - result_set = set() - - set1 = set(nums1) - for num in nums2: - if num in set1: - result_set.add(num) # set1里出现的nums2元素 存放到结果 - return list(result_set) + return list(set(nums1) & set(nums2)) # 两个数组先变成集合,求交集后还原为数组 ``` diff --git a/problems/0724.寻找数组的中心索引.md b/problems/0724.寻找数组的中心索引.md index 3ed68d47..b4115893 100644 --- a/problems/0724.寻找数组的中心索引.md +++ b/problems/0724.寻找数组的中心索引.md @@ -89,7 +89,16 @@ class Solution { ## Python -```python +```python3 +class Solution: + def pivotIndex(self, nums: List[int]) -> int: + numSum = sum(nums) #数组总和 + leftSum = 0 + for i in range(len(nums)): + if numSum - leftSum -nums[i] == leftSum: #左右和相等 + return i + leftSum += nums[i] + return -1 ``` ## Go diff --git a/problems/0922.按奇偶排序数组II.md b/problems/0922.按奇偶排序数组II.md index 92db204d..97d7091e 100644 --- a/problems/0922.按奇偶排序数组II.md +++ b/problems/0922.按奇偶排序数组II.md @@ -149,7 +149,32 @@ class Solution { ## Python -```python +```python3 +#方法2 +class Solution: + def sortArrayByParityII(self, nums: List[int]) -> List[int]: + result = [0]*len(nums) + evenIndex = 0 + oddIndex = 1 + for i in range(len(nums)): + if nums[i] % 2: #奇数 + result[oddIndex] = nums[i] + oddIndex += 2 + else: #偶数 + result[evenIndex] = nums[i] + evenIndex += 2 + return result + +#方法3 +class Solution: + def sortArrayByParityII(self, nums: List[int]) -> List[int]: + oddIndex = 1 + for i in range(0,len(nums),2): #步长为2 + if nums[i] % 2: #偶数位遇到奇数 + while nums[oddIndex] % 2: #奇数位找偶数 + oddIndex += 2 + nums[i], nums[oddIndex] = nums[oddIndex], nums[i] + return nums ``` ## Go diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md index 9e71ec0d..71c46401 100644 --- a/problems/0977.有序数组的平方.md +++ b/problems/0977.有序数组的平方.md @@ -252,6 +252,24 @@ func sortedSquares(_ nums: [Int]) -> [Int] { } ``` +Ruby: + +```ruby +def sorted_squares(nums) + left, right, result = 0, nums.size - 1, [] + while left <= right + if nums[left]**2 > nums[right]**2 + result << nums[left]**2 + left += 1 + else + result << nums[right]**2 + right -= 1 + end + end + result.reverse +end +``` + ----------------------- diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 9acda71c..8c3a5831 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -160,34 +160,21 @@ Python: class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: - lengthA,lengthB = 0,0 - curA,curB = headA,headB - while(curA!=None): #求链表A的长度 - curA = curA.next - lengthA +=1 - - while(curB!=None): #求链表B的长度 - curB = curB.next - lengthB +=1 - - curA, curB = headA, headB + """ + 根据快慢法则,走的快的一定会追上走得慢的。 + 在这道题里,有的链表短,他走完了就去走另一条链表,我们可以理解为走的快的指针。 - if lengthB>lengthA: #让curA为最长链表的头,lenA为其长度 - lengthA, lengthB = lengthB, lengthA - curA, curB = curB, curA + 那么,只要其中一个链表走完了,就去走另一条链表的路。如果有交点,他们最终一定会在同一个 + 位置相遇 + """ + cur_a, cur_b = headA, headB # 用两个指针代替a和b - gap = lengthA - lengthB #求长度差 - while(gap!=0): - curA = curA.next #让curA和curB在同一起点上 - gap -= 1 - while(curA!=None): - if curA == curB: - return curA - else: - curA = curA.next - curB = curB.next - return None + while cur_a != cur_b: + cur_a = cur_a.next if cur_a else headB # 如果a走完了,那么就切换到b走 + cur_b = cur_b.next if cur_b else headA # 同理,b走完了就切换到a + + return cur_a ``` Go: