剑指offer list部分
题1:从尾到头打印数据
思路一:利用list中的add(index,value)
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
ListNode tmp = listNode;
while (tmp!=null)
{
list.add(0,tmp.val);
tmp = tmp.next;
}
return list;
}
}
思路二:利用递归
public class Solution {
ArrayList list = new ArrayList();
public ArrayList printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
printListFromTailToHead(listNode.next);
list.add(listNode.val);
}
return list;
}
}
思路三:栈
import java.util.Stack;
public class Solution{
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> sc = new Stack<>(); //栈是先进后出
while(listNode != null){ //若当前ListNode类对象不为空
sc.push(listNode.val);//则将当前对象的头节点存入栈中
listNode = listNode.next; //将当前对象的下一个节点对象赋给listNode对象,对象传对象
}
ArrayList<Integer> list = new ArrayList<>();
while(!sc.isEmpty()){ //若当前的栈内存不为空
list.add(sc.pop());//出栈,先进后出,即先输出后进来的
}
return list;
}
}
题2:输入链表中倒数第k个数字
思路一:快慢指针
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head==None or k<=0:
return None
#设置两个指针,p2指针先走(k-1)步,然后再一起走,当p2为最后一个时,p1就为倒数第k个 数
p2=head
p1=head
#p2先走,走k-1步,如果k大于链表长度则返回 空,否则的话继续走
while k>1:
if p2.next!=None:
p2=p2.next
k-=1
else:
return None
#两个指针一起 走,一直到p2为最后一个,p1即为所求
while p2.next!=None:
p1=p1.next
p2=p2.next
return p1
思路二:栈 pop第n个
import java.util.Stack;
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head == null || k ==0 ){
return null;
}
//可以先把链表反转,然后找出第k个
Stack<ListNode> stack = new Stack<ListNode>();
int count = 0;
while(head != null){
stack.push(head);
head = head.next;
count++;
}
if(count < k){
return null;
}
ListNode knode = null;
for(int i = 0; i < k; i++){
knode = stack.pop();
}
return knode;
}
}
题3:反转链表
思路一:两个指针循环在链表滑动
(注意考虑链表只要一个值或者空的特殊情况)
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode newHead = null;
ListNode currentHead = head;
if(head == null || head.next == null){
return head;
}
while(currentHead != null){
ListNode next = currentHead.next;
currentHead.next = newHead;
newHead = currentHead;
currentHead = next;
}
题4:合并两个有序链表并排序
思路1:如图
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if (list1 == null){
return list2;
}
if (list2 == null){
return list1;
}
ListNode res = null;
if(list1.val < list2.val){
res = list1;
res.next = Merge(list1.next, list2);
}
else{
res = list2;
res.next = Merge(list2.next, list1);
}
return res;
}
}
题5 复杂链表的复制
思路一:复制 分割
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if (pHead == null){
return null;
}
//复制节点
RandomListNode currentnode = pHead;
while(currentnode!= null){
RandomListNode clonenode = new RandomListNode(currentnode.label);
clonenode.next = currentnode.next;
currentnode.next = clonenode;
currentnode = clonenode.next;
}
//复制random指针
currentnode = pHead;
while(currentnode != null){
if(currentnode.random!=null){
currentnode.next.random = currentnode.random.next;
}
currentnode = currentnode.next.next;
}
//分割
RandomListNode head =pHead.next;
RandomListNode tmp = head;
currentnode = pHead;
while(currentnode.next!=null){
tmp = currentnode.next;
currentnode.next = tmp.next;
currentnode = tmp;
}
return head;
}
}
思路二:hashmap
remain
题6 删除链表重复的节点
remain
题7 求两个链表第一个公共节点
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null){return null;}
ListNode p1 = pHead1;
ListNode p2 = pHead2;
while(p1 != p2){
p1 = p1.next;
p2 = p2.next;
if(p1 != p2){
if(p1 == null) p1=pHead2;
if(p2 == null) p2=pHead1;
}
}
return p1;
}
}
题8 链表中环的入口节点
思路:1.判断链表中有环 -> 2.得到环中节点的数目 -> 3.找到环中的入口节点
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead == null){return null;}
ListNode l = pHead;
ListNode r = pHead;
boolean flag = false;
//判断是否有环;
while(r!=null && r.next!=null){
l=l.next;
r=r.next.next;
if(l == r){
flag = true;
break;
}
}
if(!flag){
return null;
}
//环的节点数
else{
int n=1;
r=r.next;
while(l!=r){
r=r.next;
n++;
}
ListNode l1=pHead;
ListNode r1=pHead;
for(int i=0; i<n; i++){
r1=r1.next;
}
while(l1 != r1){
l1 = l1.next;
r1 = r1.next;
}
return l1;
}
}
}