最近在学习数据结构和算法,目前学习到链表,这里主要分析下关于链表涉及的面试题解决思路和实现代码,本人熟悉java,所以实现都使用java。废话不多说请看第一题:
反转单向链表(在leetcode上的题目地址:反转链表)
题目描述:
给定一个单项链表:A--->B--->C--->D--->E---null,编写一个函数反转这个单项链表,输出:E--->D---C--->B--->A--->null。
算法描述:
这个题目对思维难度的考察不大,很容易理解,就是要把链表反转过来,主要考察的是对代码实现的能力和简洁性比较高一点。可以使用迭代的方式来实现,下面来简单分析下,我们需要把链表的每个节点的next指针重新指向当前节点的上一个节点,算法如下:
1、定义三个节点:头节点(head)、前驱节点(pre)和当前节点(cur)
2、进入循环,遍历链表,首先获取当前节点的下一个节点nextNode=cur.next
3、判断next是否为空,为空,则head节点指向当前节点
4、把当前节点cur.next指向前驱pre节点,前驱节点pre指向当前节点cur,当前节点cur指向nextNode
5、继续循环,直到遍历完整个链表
这样表述可能不是很直观,下面用图来形象展示这个过程
初始化时:
不停遍历的变化:
可以看到最后链表反转过来了。代码实现如下:
@Data
public class Node<T extends Comparable<T>> {
private T item;
private Node<T> next;
public Node(T item) {
if(item == null) {
throw new RuntimeException("不能储存null对象");
}
this.item = item;
}
@Override
public String toString() {
StringBuffer result = new StringBuffer();
result.append(item.toString()).append("--->");
Node<T> p = next;
while(p != null) {
result.append(p.item.toString()).append("--->");
p = p.next;
}
result.append("null");
return result.toString();
}
}
class Solution{
public static <T extends Comparable<T>> Node<T> reverseList(Node<T> list) {
Node<T> pre = null;
Node<T> head = null;
Node<T> cur = list;
while(cur != null) {//循环遍历,没有到链表结尾就不停循环
Node<T> next = cur.getNext();//先存储下一个节点
if(next == null) {//如果next节点为空,说明已经遍历到最后一个节点了
head = cur;//头节点指向最后节点,当前节点已经是最后节点了
}
cur.setNext(pre);//当前节点的next节点指向前驱节点
pre = cur;//更新前驱节点为当前节点
cur = next;//更新当前节点为下一个节点
}
return head;//循环结束返回链表
}
}
可以简单的看一下此算法的复杂度:
- 时间复杂度:假设链表的长度为n,因为要遍历链表的每一个节点,所以时间复杂度就是O(n)
- 空间复杂度:O(1)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。