反转链表
题目源自牛客网反转链表_牛客题霸_牛客网 (nowcoder.com)
需要实现一个空间复杂度O(1),时间复杂度O(n)的算法
注意本题中是一个不带头结点的链表
破题思路:
可以加一个头结点,然后将头结点掰下来,对其进行头插法,实现链表原地反转
代码python版
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @return ListNode类
#
class Solution:
def ReverseList(self , head: ListNode) -> ListNode:
# write code here
#加一个头结点
l = ListNode(0)
l.next = None
p = head
while p != None:
q = p.next
p.next = l.next
l.next = p
p = q
return l.next
三数之和
题目源自力扣15. 三数之和 - 力扣(LeetCode)
破题思路,排序 + 双指针的思想,套用在三指针上,每一次循环遍历时,都让k指向i的后一个位置,j始终指向列表的最后一端。然后让i,k,j互不相等时,使得指针指向的数组中的元素和为0.
python代码:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()
ans = []
for i in range(n):
k = i + 1
j = n - 1
if nums[i] > 0:
break
if i >= 1 and nums[i] == nums[i - 1]:
continue
while k < j:
total = nums[i] + nums[k] + nums[j]
if total > 0:
j -= 1
elif total < 0:
k += 1
else:
ans.append([nums[i], nums[k], nums[j]])
while k != j and nums[k] == nums[k + 1]:
k += 1
while k != j and nums[j] == nums[j - 1]:
j -= 1
k += 1
j -= 1
return ans
回文链表
给你一个单链表的头节点 head
,请你判断该链表是否为回文链表。如果是,返回 true
;否则,返回 false
。
破题思路:
利用栈的特性,先找到单链表的中间结点,链表的前半部分入栈,链表的后边部分依次扫描,如果每扫描到的数都是栈中的栈顶元素,就将栈顶元素弹出,链表指针后移,以此类推,直到栈空说明为回文链表,反之不是回文链表。当然链表的结点数为奇数偶数需要一点特别处理,基本类似,奇数结点,就跳过中间结点,从中间结点后一个结点搜索,其他的跟偶数结点一样的处理方式。找到单链表的中心结点有一个比较好的算法是快慢指针法,只需扫描一遍链表就能找到链表中点。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
stack = []
fast = head
slow = head
p = head
#快慢指针法找到链表中点
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast != None:
#此时结点为奇数个
while p != slow:
stack.append(p.val)
p = p.next
p = p.next
while p!= None and stack != []:
if p.val == stack[-1]:
stack.pop()
p = p.next
else:
return False
slow = slow.next
#此时结点为偶数个
while p != None and p.next != slow:
stack.append(p.val)
p = p.next
while p!= None and stack != []:
if p.val == stack[-1]:
stack.pop()
p = p.next
else:
return False
if stack == []:
return True
else:
return False
环形链表
题目源自力扣141. 环形链表 - 力扣(LeetCode)
思路一:同样是快慢指针,当快慢指针相遇时,就遇到了环
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
fast = head
slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
思路二:哈希表法,从头结点开始,每走过一个点加入到集合中,判断该点是否在集合中出现过,出现过就返回True,存在环
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
s = set()
p = head
while p != None:
if p not in s:
s.add(p)
p = p.next
else:
return True
return False