算法编程解题思路:
- 给出算法的基本设计思想
- 根据设计思想,采用 Java 或者 python 语言描述算法,关键之处给出注释
- 说明时间复杂度和空间复杂度
一、顺序表
1、长度为 n 的顺序表 L,编写一个时间复杂度为 O(n),空间复杂度为O(1) 的算法,该算法删除线性表中所有值为 x 的数据元素。
方法一:定义指针 index,遍历数组的元素,当元素的值不为 x 时,将当前元素前置到 index 位置上,同时 index 自增。
def function(nums, x):
index = 0
for i in range(0, len(nums)):
if nums[i] != x:
nums[index] = nums[i]
index += 1
print(nums[0: index])
方法二:定义变量 count,用于统计值为 x 的数量,遍历数组的元素,当元素的值不为 x,将下标为 i 的元素前置到 i - count 的位置。
def function(nums, x):
count = 0
for i in range(0, len(nums)):
if nums[i] == x:
count += 1
else:
nums[i - count] = nums[i]
print(nums[0: len(nums) - count])
2、从顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同
思路:定义指针 index,遍历数组的元素,当元素 nums[index] 不等于 nums[i] 时,说明 nums[index] 不需要被删除,所以,index 先自增,然后,将当前元素前置到 index 位置上。
举例说明:
def function(nums):
index = 0
for i in range(1, len(nums)):
if nums[index] != nums[i]:
index += 1
nums[index] = nums[i]
print(nums[0: index + 1])
3、线性表(a1, a2, a3, ……,an)中元素递增有序,且按顺序存储于计算机内。要求设计一算法完成用最少的时间在表中查找值为 x 的元素,若找到将其与后继元素位置想交换,若找不到将其插入表中,并使表中的元素仍然递增有序。
def function(nums, target):
low = 0
high = len(nums) - 1
mid = 0
while low <= high:
mid = (low + high) // 2
if nums[mid] == target:
break
if nums[mid] < target:
low = mid + 1
else:
high = mid - 1
if nums[mid] == target and mid < len(nums) - 1:
nums[mid], nums[mid+1] = nums[mid+1], nums[mid]
if low > high:
nums.append(0)
for i in range(len(nums)-1, high, -1):
nums[i] = nums[i-1]
nums[low] = target
4、将 n(n > 0) 个整数存放到一维数组 R 中。试设计一个在时间和空间两方面都尽可能高效的算法。将 R 中保存的序列循环左移 p (0<p<n)个位置。
def reverse(nums, start, end):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
print(nums)
def function(nums, p):
reverse(nums, 0, p-1)
reverse(nums, p, len(nums)-1)
reverse(nums, 0, len(nums)-1)
5、一个长度为 L 的升序列 S,处在 1/2 个位置的数称为 S 的中位数。S1=(11, 13, 15, 17, 19),S2=(2, 4, 6, 8, 20),现在有两个等长的升序序列 A = (11, 13, 15, 17, 19) 和 B = (2, 4, 6, 8, 20),试设计一个在时间和空间两个方面都尽可能高效的算法,找出两个序列 A 和 B 的中位数。
6、已知一个整数序列 A = (a0, a1, ……, an-1),其中,0 <= ai < n。若某个元素的数量超过一半,则称之为主元素。请设计一个高效的算法,找出 A = (0, 5, 5, 3, 5, 7, 5, 5) 的主元素。
def function(nums):
flag = nums[0]
count = 1
for i in range(1, len(nums)):
flag = nums[i] if count == 0 else flag
count += 1 if flag == nums[i] else -1
print(flag)
二、链表
引入头结点后,第一个结点的位置被存放在头结点的指针域中,有点如下:
- 在链表中的第一个位置和其他位置上的结点操作一致,无须进行特殊处理;
- 空链表和非空链表的处理一致。
尾插法建表
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def create_link_list(nums):
head = ListNode(0)
pointer = head
for i in nums:
temp = ListNode(i)
pointer.next = temp
pointer = pointer.next
return head
create_link_list([1, 2, 3, 4, 5])
遍历链表
def print_link(head):
pointer = head.next
while pointer is not None:
print(pointer.val)
pointer = pointer.next
1、头插法实现单链表反转或者就地逆置单链表
def function(head):
pointer = head.next
p_index = ListNode(0)
head = ListNode(0)
while pointer is not None:
p_index = pointer
pointer = pointer.next
p_index.next = head.next
head.next = p_index
2、设 head 为带头结点的单链表,编写算法实现从尾到头反向输出每个节点的值
def function(head): # head 链表参照尾插法自己创建,输入列表,输出链表
stack = Stack() # Stack 是作者基于列表封装的类,实现了栈的功能
pointer = head.next
while pointer is not None:
stack.push(pointer.val)
pointer = pointer.next
while not stack.is_empty():
print(stack.pop())
3、有一个带头结点的单链表 head,涉及一个算法使其元素递增有序。
思路:插入排序法实现链表的排序
def function(head):
pointer = head.next
head = ListNode(0)
while pointer is not None:
p_index = pointer
pointer = pointer.next
temp_index = head
while temp_index.next is not None and temp_index.next.val < p_index.val:
temp_index = temp_index.next
p_index.next = temp_index.next
temp_index.next = p_index
4、给定两个单链表,编写算法找出两个链表的公共结点。
思路:如果链表有公共结点,那么,两个链表从公共结点到尾结点一定是相同的,所以,先将其中较长的链表遍历至和较短的链表相同长度,然后,同时遍历并判断当前两个链表的结点是否相同。
def getIntersectionNode(headA, headB):
countA = 0
countB = 0
index_A = headA
while index_A is not None:
countA += 1
index_A = index_A.next
index_B = headB
while index_B is not None:
countB += 1
index_B = index_B.next
distance = 0
long_link = ListNode(0)
short_link = ListNode(0)
if countA - countB > 0:
distance = countA - countB
long_link = headA
short_link = headB
else:
distance = countB - countA
long_link = headB
short_link = headA
for i in range(0, distance):
long_link = long_link.next
while long_link is not None:
if long_link == short_link:
return long_link
long_link = long_link.next
short_link = short_link.next
return None
5、请你设计并实现一个满足 LRU(最近最少)使用约束的数据结构