1. 1 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.(栈)
public ArrayList< Integer> printListFromTailToHead ( ListNode node) {
ArrayList< Integer> result = new ArrayList < > ( ) ;
if ( node == null)
return result;
Stack< Integer> stack = new Stack < > ( ) ;
while ( node != null) {
stack. push ( node. val) ;
node = node. next;
}
while ( stack. size ( ) != 0 ) {
result. add ( stack. pop ( ) ) ;
}
return result;
}
1. 2 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.(递归)
public ArrayList< Integer> printListFromTailToHead ( ListNode node) {
ArrayList< Integer> result = new ArrayList < > ( ) ;
if ( node == null)
return result;
core ( node, result) ;
return result;
}
private void core ( ListNode node, ArrayList< Integer> result) {
if ( node. next != null) {
core ( node. next, result) ;
}
result. add ( node. val) ;
}
2.1 输入一个链表,输出该链表中倒数第k个结点
方法一:快慢指针,时间复杂度O(n)
public ListNode FindKthToTail ( ListNode head, int k) {
if ( head == null || k < 1 )
return null;
ListNode fast = head;
while ( k != 1 && fast. next != null) {
fast = fast. next;
k-- ;
}
if ( k != 1 )
return null;
while ( fast. next != null) {
fast = fast. next;
head = head. next;
}
return head;
}
方法二:两趟处理,第一趟求出链表长度N,第二趟走N-k-1步即可
public ListNode FindKthToTail ( ListNode head, int k) {
if ( head == null || k < 1 )
return null;
int len = 0 ;
ListNode temp = head;
while ( temp != null) {
len++ ;
temp = temp. next;
}
int diff = len - k;
while ( diff > 0 ) {
head = head. next;
diff-- ;
}
if ( diff != 0 )
return null;
return head;
}
方法三:利用栈,弹出的第k个即为倒数第k个节点(简单,略)
2.2 输入一个链表,反转链表
方法一:直接翻转
public ListNode ReverseList ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode pre = null;
ListNode cur = head;
ListNode next = null;
while ( cur != null) {
next = cur. next;
cur. next = pre;
pre = cur;
cur = next;
}
return pre;
}
方法二:利用栈(简单、略)
2.3 输入两个单调递增的链表,输出两个链表合成后的链表,合成后的链表满足单调不减规则
public ListNode Merge ( ListNode list1, ListNode list2) {
if ( list1 == null)
return list2;
if ( list2 == null)
return list1;
ListNode head = null;
ListNode temp = null;
while ( list1 != null && list2 != null) {
if ( list1. val < list2. val) {
if ( head == null) {
head = list1;
temp = list1;
} else {
temp. next = list1;
temp = list1;
}
list1 = list1. next;
} else {
if ( head == null) {
head = list2;
temp = list2;
} else {
temp. next = list2;
temp = list2;
}
list2 = list2. next;
}
}
if ( list1 != null) {
temp. next = list1;
} else {
temp. next = list2;
}
return head;
}
2.3 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
public RandomListNode Clone ( RandomListNode head) {
if ( head == null)
return null;
RandomListNode temp = head;
while ( temp != null) {
RandomListNode copy = new RandomListNode ( temp. label) ;
RandomListNode next = temp. next;
temp. next = copy;
copy. next = next;
temp = next;
}
temp = head;
while ( temp != null) {
RandomListNode random = temp. random;
RandomListNode next = temp. next;
if ( random != null) {
next. random = random. next;
}
temp = next. next;
}
temp = head;
RandomListNode newHead = temp. next;
while ( temp != null) {
RandomListNode next = temp. next;
RandomListNode tempNext = next. next;
temp. next = tempNext;
if ( tempNext == null) {
next. next = tempNext;
break ;
} else {
next. next = tempNext. next;
}
temp = temp. next;
}
return newHead;
}
2.4 输入两个链表,找出它们的第一个公共结点
public ListNode FindFirstCommonNode ( ListNode head1, ListNode head2) {
if ( head1 == null || head2 == null) {
return null;
}
int len1 = 1 ;
int len2 = 1 ;
ListNode temp1 = head1;
ListNode temp2 = head2;
while ( temp1. next != null) {
len1++ ;
temp1 = temp1. next;
}
while ( temp2. next != null) {
len2++ ;
temp2 = temp2. next;
}
if ( temp1 != temp2) {
return null;
}
int diff = len1 - len2;
temp1 = head1;
temp2 = head2;
if ( diff > 0 ) {
while ( diff != 0 ) {
temp1 = temp1. next;
diff-- ;
}
while ( temp1 != null) {
if ( temp1 == temp2) {
return temp1;
}
temp1 = temp1. next;
temp2 = temp2. next;
}
} else {
while ( diff != 0 ) {
temp2 = temp2. next;
diff++ ;
}
while ( temp1 != null) {
if ( temp1 == temp2) {
return temp1;
}
temp1 = temp1. next;
temp2 = temp2. next;
}
}
return null;
}
2.5 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null
public ListNode EntryNodeOfLoop ( ListNode head) {
if ( head == null || head. next == head)
return head;
ListNode fast = head. next;
ListNode slow = head;
while ( fast != slow && fast != null) {
fast = fast. next;
slow = slow. next;
if ( fast != null) {
fast = fast. next;
} else {
return null;
}
}
if ( fast == null) {
return null;
}
fast = fast. next;
int len = 1 ;
while ( fast != slow) {
len++ ;
fast = fast. next;
}
fast = head;
slow = head;
while ( len != 1 ) {
fast = fast. next;
len-- ;
}
while ( fast. next != slow) {
fast = fast. next;
slow = slow. next;
}
return slow;
}
2.6 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
方法一:使用辅助数据结构哈希表
public ListNode deleteDuplication ( ListNode head) {
if ( head == null)
return head;
HashMap< Integer, Integer> map = new HashMap < Integer, Integer> ( ) ;
ListNode temp = head;
while ( temp != null) {
Integer count = map. get ( temp. val) ;
if ( count == null) {
map. put ( temp. val, 1 ) ;
} else {
map. put ( temp. val, count+ 1 ) ;
}
temp = temp. next;
}
temp = head;
ListNode result = null;
ListNode cur = null;
while ( temp != null) {
Integer count = map. get ( temp. val) ;
if ( count > 1 ) {
while ( count != 0 ) {
temp = temp. next;
count-- ;
}
} else {
if ( result == null) {
result = temp;
cur = temp;
} else {
cur. next = temp;
cur = temp;
}
temp = temp. next;
}
}
if ( cur != null)
cur. next = null;
return result;
}
使用递归处理
public ListNode deleteDuplication ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
if ( head. val == head. next. val) {
ListNode node = head. next;
while ( node != null && node. val == head. val) {
node = node. next;
}
return deleteDuplication ( node) ;
} else {
head. next = deleteDuplication ( head. next) ;
return head;
}
}