160. 相交链表
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
【示例 1】
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
【示例 2】
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Reference of the node with value = 2
输入解释:相交节点的值为 2(注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
【示例 3】
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 解释:这两个链表不相交,因此返回 null。
注意:
- 如果两个链表没有交点,返回 null.
- 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n)时间复杂度,且仅用 O(1) 内存。
尝试思路:
1、取各个链表的长度
2、根据链表长度差值,找到同步起点位置
3、同步两个指针,比较节点是否相同,若不同则继续找,直到结束
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
la, lb = 0, 0
pA, pB = headA, headB
while pA:
la += 1
pA = pA.next
while pB:
lb += 1
pB = pB.next
diff = abs(la - lb)
if la >= lb:
for i in range(diff):
headA = headA.next
else:
for i in range(diff):
headB = headB.next
while headA:
if headA == headB:
return headA
headA = headA.next
headB = headB.next
return
169. 多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
【示例 1】输入:[3,2,3] 输出:3
【示例 2】输入:[2,2,1,1,1,2,2] 输出:2
进阶: 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
尝试思路1:
1、用字典进行统计,数字为key,计数为value
2、找到value超过n/2的key
代码:
class Solution:
def majorityElement(self, nums: List[int]) -> int:
stat = dict()
for i in range(len(nums)):
if str(nums[i]) in stat.keys():
stat[str(nums[i])] += 1
else:
stat[str(nums[i])] = 1
if stat[str(nums[i])] > len(nums) // 2:
return nums[i]
尝试思路2:
1、对列表进行排序
2、若当前元素与前一个元素一致,则计数加1,判断计数与n/2的大小
代码:
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
for i in range(len(nums)):
if i == 0 or nums[i] != nums[i - 1]:
val = 1
elif nums[i] == nums[i - 1]:
val += 1
if val > len(nums) // 2:
return nums[i]
206. 反转链表
反转一个单链表。
【示例】输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
进阶: 你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
尝试思路1:暴力法
1、收集链表中所有值
2、反转列表
3、重建链表
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
l = []
while head:
l.append(head.val)
head = head.next
l.reverse()
node = ListNode(0, None)
result = node
for i in range(len(l)):
node.next = ListNode(l[i], None)
node = node.next
return result.next
尝试思路2:修改节点值
1、记录链表值
2、从头开始修改链表值
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
l = []
result = head
while head:
l.append(head.val)
head = head.next
l.reverse()
head = result
for i in range(len(l)):
head.val = l[i]
head = head.next
return result
尝试思路3:修改原链表指向方向
设置三个指针
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
p1 = head
if p1 == None or p1.next == None:
return p1
elif p1.next.next == None:
p2 = p1.next
p1.next = None
p2.next = p1
return p2
else:
p2, p3 = head.next, head.next.next
p1.next = None
while p3:
p2.next = p1
p1 = p2
p2 = p3
p3 = p2.next
p2.next = p1
return p2