【数据结构】时间复杂度和空间复杂度
**数据结构**
在计算机科学中,数据结构是指组织、存储和操作数据的方式。它是计算机程序设计中的一个基本概念,直接影响到程序的性能、效率和可维护性。
**时间复杂度**
时间复杂度(Time Complexity)是指算法执行所需的时间与输入大小的关系。它通常用大O符号表示,不考虑常数项。例如,算法A的时间复杂度为O(n),意味着该算法的执行时间随着输入大小的增加而线性增长。
**空间复杂度**
空间复杂度(Space Complexity)是指算法所需的存储空间与输入大小的关系。它也通常用大O符号表示,不考虑常数项。例如,算法B的空间复杂度为O(1),意味着该算法的存储空间不随输入大小的增加而增长。
**时间复杂度分类**
根据时间复杂度的增长速度,可以将其分为以下几类:
* **O(1)**:常数时间复杂度,表示算法执行所需的时间不随输入大小的增加而变化。
* **O(log n)**:对数时间复杂度,表示算法执行所需的时间与输入大小的对数成正比。
* **O(n)**:线性时间复杂度,表示算法执行所需的时间随着输入大小的增加而线性增长。
* **O(n log n)**:线性对数时间复杂度,表示算法执行所需的时间与输入大小的乘积成正比。
* **O(n^2)**:平方时间复杂度,表示算法执行所需的时间随着输入大小的增加而平方增长。
* **O(2^n)**:指数时间复杂度,表示算法执行所需的时间与输入大小的指数成正比。
**空间复杂度分类**
根据空间复杂度的增长速度,可以将其分为以下几类:
* **O(1)**:常数空间复杂度,表示算法所需的存储空间不随输入大小的增加而变化。
* **O(log n)**:对数空间复杂度,表示算法所需的存储空间与输入大小的对数成正比。
* **O(n)**:线性空间复杂度,表示算法所需的存储空间随着输入大小的增加而线性增长。
* **O(n log n)**:线性对数空间复杂度,表示算法所需的存储空间与输入大小的乘积成正比。
**时间复杂度和空间复杂度的例子**
以下是几个例子的时间复杂度和空间复杂度:
* **查找元素在数组中的位置**
* 时间复杂度:O(n)
* 空间复杂度:O(1)
def find_element(arr, target): for i in range(len(arr)): if arr[i] == target: return i return -1arr = [1,2,3,4,5] target =3print(find_element(arr, target)) # Output:2
* **查找元素在链表中的位置**
* 时间复杂度:O(n)
* 空间复杂度:O(1)
class Node: def __init__(self, data): self.data = data self.next = Nonedef find_element(head, target): current = head while current is not None: if current.data == target: return True current = current.next return Falsehead = Node(1) head.next = Node(2) head.next.next = Node(3) print(find_element(head,3)) # Output: True
* **排序数组**
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
def sort_array(arr): for i in range(len(arr)): for j in range(i +1, len(arr)): if arr[i] > arr[j]: arr[i], arr[j] = arr[j], arr[i] return arrarr = [5,2,8,3,1] print(sort_array(arr)) # Output: [1,2,3,5,8]
* **排序链表**
* 时间复杂度:O(n log n)
* 空间复杂度:O(1)
class Node: def __init__(self, data): self.data = data self.next = Nonedef sort_list(head): current = head while current is not None: next_node = current.next while next_node is not None: if current.data > next_node.data: current.data, next_node.data = next_node.data, current.data next_node = next_node.next current = current.next return headhead = Node(5) head.next = Node(2) head.next.next = Node(8) head.next.next.next = Node(3) print(sort_list(head).data) # Output:1
* **查找两个链表的交点**
* 时间复杂度:O(n + m)
* 空间复杂度:O(1)
class Node: def __init__(self, data): self.data = data self.next = Nonedef find_intersection(head1, head2): current1 = head1 current2 = head2 while current1 is not None and current2 is not None: if current1 == current2: return current1 current1 = current1.next current2 = current2.next return Nonehead1 = Node(1) head1.next = Node(2) head1.next.next = Node(3) head2 = Node(4) head2.next = Node(5) head2.next.next = head1.next.nextprint(find_intersection(head1, head2).data) # Output:3
* **查找两个链表的交点(优化版)**
* 时间复杂度:O(n + m)
* 空间复杂度:O(1)
class Node: def __init__(self, data): self.data = data self.next = Nonedef find_intersection(head1, head2): len1 =0 current1 = head1 while current1 is not None: len1 +=1 current1 = current1.next len2 =0 current2 = head2 while current2 is not None: len2 +=1 current2 = current2.next if len1 > len2: longer_head = head1 shorter_head = head2 else: longer_head = head2 shorter_head = head1 diff = abs(len1 - len2) for _ in range(diff): longer_head = longer_head.next while longer_head is not None and shorter_head is not None: if longer_head == shorter_head: return longer_head longer_head = longer_head.next shorter_head = shorter_head.next return Nonehead1 = Node(1) head1.next = Node(2) head1.next.next = Node(3) head2 = Node(4) head2.next = Node(5) head2.next.next = head1.next.nextprint(find_intersection(head1, head2).data) # Output:3
* **查找两个链表的交点(优化版)**
* 时间复杂度:O(n + m)
* 空间复杂度:O(1)
class Node: def __init__(self, data): self.data = data self.next = Nonedef find_intersection(head1, head2): len1 =0 current1 = head1 while current1 is not None: len1 +=1 current1 = current1.next len2 =0 current2 = head2 while current2 is not None: len2 +=1 current2 = current2.next if len1 > len2: longer_head = head1 shorter_head = head2 else: longer_head = head2 shorter_head = head1 diff = abs(len1 - len2) for _ in range(diff): longer_head = longer_head.next while longer_head is not None and shorter_head is not None: if longer_head == shorter_head: return longer_head longer_head = longer_head.next shorter_head = shorter_head.next return Nonehead1 = Node(1) head1.next = Node(2) head1.next.next = Node(