1.链表的逆输出

栈先进后出 用java实现
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer>list=new ArrayList<>();
ListNode p=listNode;
while(p!=null){
list.add(0,p.val);
p=p.next;
}
return list;
}
}
时间复杂度:O(n) 空间复杂度O(n)
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
std::stack<int> s1;
ListNode* h=head;
while(h!=NULL){
s1.push(h->val);
h=h->next;
}
vector<int>result;
while(!s1.empty()){
result.push_back(s1.top());
s1.pop();
}
return result;
}
};
作者:zhouying1999
链接:https://juejin.cn/post/6844904116863369230
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2.链表中倒数第k个节点

链接:https://www.nowcoder.com/questionTerminal/529d3ae5a407492994ad2a246518148a?answerType=1&f=discussion
来源:牛客网
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(head == null || k ==0 ){
return null;
}
ListNode slow=head;
ListNode fast=head;
for(int i=0;i<k;i++){
if(fast==null){
return null;
}
fast=fast.next;
}
while(fast!=null){
slow=slow.next;
fast=fast.next;
}
return slow;
}
}
3.反转链表

时间复杂度O(n) 空间复杂度O(1)
链接:https://www.nowcoder.com/questionTerminal/75e878df47f24fdc9dc3e400ec6058ca?answerType=1&f=discussion
来源:牛客网
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
// 判断链表为空或长度为1的情况
if(head == null || head.next == null){
return head;
}
ListNode pre = null; // 当前节点的前一个节点
ListNode next = null; // 当前节点的下一个节点
while( head != null){
next = head.next; // 记录当前节点的下一个节点位置;
head.next = pre; // 让当前节点指向前一个节点位置,完成反转
pre = head; // pre 往右走
head = next;// 当前节点往右继续走
}
return pre;
}
}
4.合并两个排序的链表

sollution1 用一个新的指针
时间复杂度O(n) 空间复杂度O(1)
链接:https://www.nowcoder.com/questionTerminal/d8b6b4358f774294a89de2a6ac4d9337?answerType=1&f=discussion
来源:牛客网
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode h = new ListNode(-1);
ListNode cur = h;
while(list1 != null && list2 !=null){
if(list1.val<=list2.val){
cur.next = list1;
list1 = list1.next;
}else{
cur.next = list2;
list2 = list2.next;
}
cur = cur.next;
}
if(list1!=null) cur.next = list1;
if(list2!=null) cur.next = list2;
return h.next;
}
}
sollution2 递归
时间复杂度O(n) 空间复杂度O(1)
链接:https://www.nowcoder.com/questionTerminal/d8b6b4358f774294a89de2a6ac4d9337?answerType=1&f=discussion
来源:牛客网
//递归
public ListNode Merge1(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
} else if (list2 == null) {
return list1;
}else{
if(list1.val<list2.val){
list1.next=Merge1(list1.next, list2);
return list1;
}else {
list2.next=Merge1(list1, list2.next);
return list2;
}
}
}
5.复杂链表的复制

hashmap存
时间复杂度O(n) 空间复杂度O(n)
链接:https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba?answerType=1&f=discussion
来源:牛客网
class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if (pHead == null) {
return pHead;
}
RandomListNode p1 = pHead;
RandomListNode p2 = pHead;
HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
while (p1 != null) {
map.put(p1, new RandomListNode(p1.label));
p1 = p1.next;
}
while (p2 != null) {
if (p2.next != null) {
map.get(p2).next = map.get(p2.next);
} else {
map.get(p2).next = null;
}
map.get(p2).random = map.get(p2.random);
p2 = p2.next;
}
return map.get(pHead);
}
}
6.两个链表的第一个公共节点

线索:公共表尾
先算出长度差 让长的先走这个长度差 再两个一起走
跳出循环标志:两个指针的next相等
时间复杂度O(n) 空间复杂度O(1)
链接:https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46?f=discussion
来源:牛客网
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
int len1 = findListLenth(pHead1);
int len2 = findListLenth(pHead2);
if(len1 > len2){
pHead1 = walkStep(pHead1,len1 - len2);
}else{
pHead2 = walkStep(pHead2,len2 - len1);
}
while(pHead1 != NULL){
if(pHead1 == pHead2) return pHead1;
pHead1 = pHead1->next;
pHead2 = pHead2->next;
}
return NULL;
}
int findListLenth(ListNode *pHead1){
if(pHead1 == NULL) return 0;
int sum = 1;
while(pHead1 = pHead1->next) sum++;
return sum;
}
ListNode* walkStep(ListNode *pHead1, int step){
while(step--){
pHead1 = pHead1->next;
}
return pHead1;
}
};
7.链表中环的入口结点

链接:https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4?answerType=1&f=discussion
来源:牛客网
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead == null || pHead.next == null){
return null;
}
ListNode fast = pHead;
ListNode slow = pHead;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
ListNode slow2 = pHead;
while(slow2 != slow){
slow2 = slow2.next;
slow = slow.next;
}
return slow2;
}
}
return null;
}
}
8.删除链表的重复结点

时间复杂度:O(n) 空间复杂度:O(1)
链接:https://www.nowcoder.com/questionTerminal/fc533c45b73a41b0b44ccba763f866ef?answerType=1&f=discussion
来源:牛客网
public class Solution {
public ListNode deleteDuplication(ListNode pHead){
if(pHead == null || pHead.next == null){
return pHead;
}
// 自己构建辅助头结点
ListNode head = new ListNode(Integer.MIN_VALUE);
head.next = pHead;
ListNode pre = head;
ListNode cur = head.next;
while(cur!=null){
if(cur.next != null && cur.next.val == cur.val){
// 相同结点一直前进
while(cur.next != null && cur.next.val == cur.val){
cur = cur.next;
}
// 退出循环时,cur 指向重复值,也需要删除,而 cur.next 指向第一个不重复的值
// cur 继续前进
cur = cur.next;
// pre 连接新结点
pre.next = cur;
}else{
pre = cur;
cur = cur.next;
}
}
return head.next;
}
}
9.两数相加(链表版)

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead=new ListNode(0);
ListNode p1=l1,p2=l2,cur=dummyHead;
int carry=0;
int sum=0;
while(p1!=null||p2!=null){
int x=(p1==null)?0:p1.val;
int y=(p2==null)?0:p2.val;
sum=carry+x+y;
carry=sum/10;
cur.next=new ListNode(sum%10);
cur=cur.next;
if(p1!=null)p1=p1.next;
if(p2!=null)p2=p2.next;
}
if(carry!=0){
cur.next=new ListNode(carry);
}
return dummyHead.next;
}
}
增加新的空间
10.两两交换链表中的节点
其实本质还是考链表的操作
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyhead=new ListNode(-1);
dummyhead.next=head;
ListNode preNode=dummyhead;
while(head!=null&&head.next!=null){
ListNode firstNode=head;
ListNode secondNode=head.next;
preNode.next=secondNode;
firstNode.next=secondNode.next;
secondNode.next=firstNode;
preNode=firstNode;
head=firstNode.next;
}
return dummyhead.next;
}
}
要注意的是:要设一个prenode连接到secondnode上
11.删除排序链表的重复元素

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummyhead=new ListNode(-1);
dummyhead.next=head;
ListNode pre=dummyhead;
ListNode cur=head;
int flag=0;
while(pre!=null){
while(pre!=dummyhead&&cur!=null&&cur.val==pre.val){
flag=1;
cur=cur.next;
}
if(flag==1){
pre.next=cur;
flag=0;
pre=cur;
if(cur!=null)cur=cur.next;
}else{
pre=cur;
if(cur!=null)cur=cur.next;
}
}
return dummyhead.next;
}
}
12.删除排序链表中的重复元素plus

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummyhead=new ListNode(0);
dummyhead.next=head;
ListNode pre=dummyhead;
ListNode cur=head;
int flag=0;
while(pre.next!=null){
while(cur.next!=null&&cur.next.val==pre.next.val){
flag=1;
cur=cur.next;
}
if(flag==1){
pre.next=cur.next;
flag=0;
cur=cur.next;
}else{
pre=cur;
if(cur.next!=null)cur=cur.next;
}
}
return dummyhead.next;
}
}