赞
踩
线性表是很常用的数据结构,分为顺序表和链表。
按照正常方式定义以一个数组,计算机会从内存中取出一块连续的地址来存放给定长度的数组;而链表则由若干个节点组成,且结点在内存中的存储位置不连续,链表的两个节点之间一半由一个指针从一个结点指向另一个结点,故链表结点由两部分组成:即数据域和指针域。
程序内部
单向链表与数组
单向链表:必须挨个查找元素 ——>>查找节点 O(n),插入节点 O(1),删除节点 O(1)
数组:可以随机访问元素——>>查找节点 O(1),插入节点 O(n),删除节点 O(n)
struct Node {
Node(int data):data(data),next(NULL){} //node构造函数
int data;
int *next;
};
int data[10];
int next[10];
//ind 后添加节点 p ,节点p中值为val
void add(int ind, int p, int val) {
next[ind] = p;
data[p] = val;
return ;
}
原有4G , malloc(1GB),分块后以链表链接
插入数据5,插入到尾部,删除数据1
环形链表
a.如何判定链表有环
方法1:遍历整个链表,创建一个哈希表来存储遍历过的节点(需要开辟新内存)
方法2:快慢指针
快指针每次走两步,慢指针每次走一步,如果链表有环,则快慢指针一定会相遇,当指向同一个节点时,遍历结束
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { if(head == nullptr) return false; ListNode *p = head,*q = head->next; while(p != q && q && q->next){ p = p->next; q = q->next->next; } return q && q->next; } };
b.如何判定环的起始位置
将一个指针放在链表起始位置,另一个指针放在相遇位置,两个指针一起朝后走,相遇位置就是环的起始位置
//8ms /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if(head == nullptr) return nullptr; ListNode *p = head, *q = head->next; while(p != q && q && q->next){ p = p->next; q = q->next->next; } if(q == nullptr || q->next == nullptr) return nullptr; p = head->next; q = head->next->next; while(p != q){ p = p->next; q = q->next->next; } p = head; while(p != q){ p = p->next; q = q->next; } return q; } };
//4ms /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if(head == nullptr) return nullptr; ListNode *p = head, *q = head; if(q->next == nullptr) return nullptr; do{ p = p->next; q = q->next->next; }while(p != q && q && q->next); if(q == nullptr || q->next ==nullptr) return nullptr; p = head; while(p != q) p = p->next,q = q->next; return q; } };
[快乐数] 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false
题目转化为:判断链表是否有环
如果遍历某个节点为1,说明无环,是快乐数
如果遍历到重复的节点值,说明有环,不是快乐数
class Solution { public: int getNext(int x){ int z = 0; while(x){ z += (x % 10) * (x % 10); x /= 10; } return z; } bool isHappy(int n) { int p = n, q = n; do{ p = getNext(p); q = getNext(getNext(q)); }while(p != q && q != 1); return q == 1; } };
3.重复上述操作
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { if(head == nullptr) return head; ListNode *pre = nullptr, *cur = head, *p = head->next; while(cur){//未翻转部分不为空时 cur->next = pre; pre = cur; (cur = p) && (p = p->next); } return pre; } };
递归实现
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { if(head == nullptr || head->next == nullptr) return head; ListNode *tail = head->next,*p = reverseList(head->next);//记录下一个节点地址 head->next = tail->next; tail->next = head; return p; } };
翻转前n个节点
Node *reverse(Node *head,int n){
if(n == 1) return head;
Node *tail = head->next, *p = reverse(head->next,n-1);
head->next = tail->next;
tail->next = head;
return p;
}
采用虚拟头节点
找到要反转的第一个节点,以此为新链表翻转前m-n+1位,再将第一个节点指向头节点。
class Solution { public: ListNode *reverseN(ListNode *head,int n){ if(n == 1) return head; ListNode *tail = head->next, *p = reverseN(head->next, n-1); head->next = tail->next; tail->next = head; return p; } ListNode* reverseBetween(ListNode* head, int left, int right) { ListNode ret(0,head),*p = &ret; int cnt = right - left + 1; while(--left) p = p->next; p->next = reverseN(p->next, cnt); return ret.next; } };
1.加虚拟头,p->虚拟头,q = p->next
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* __reverseN(ListNode* head, int n){ if(n == 1) return head; ListNode *tail = head->next, *p = __reverseN(head->next, n-1); head->next = tail->next; tail->next = head; return p; } ListNode* reverseN(ListNode* head, int n){ ListNode *p = head; int cnt = n; while(--n && p) p = p->next; if(p == nullptr) return head; return __reverseN(head,cnt); } ListNode* reverseKGroup(ListNode* head, int k) { ListNode ret(0,head), *p = &ret, *q = p->next; while((p->next = reverseN(q, k)) != q){ p = q; q = p->next; } return ret.next; } };
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* rotateRight(ListNode* head, int k) { if(head == nullptr) return nullptr; int n = 1; ListNode *p = head; while(p->next) p = p->next, n += 1; p->next = head; k %= n; k = n - k; while(k--) p = p->next; head = p->next; p->next = nullptr; return head; } };
设置两个指针,q先走N步,然后p,q一起走直到q指向null时,p指向删除节点的前一个结点
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode ret(0,head), *p = &ret, *q = head; while(n--){ q = q->next; } while(q){ p = p->next; q = q->next; } p->next = p->next->next; return ret.next; } };
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if(head == nullptr) return nullptr; ListNode *p = head; while(p->next){ if(p->val == p->next->val){ p->next = p->next->next; }else{ p = p->next; } } return head; } };
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if(head == nullptr) return nullptr; ListNode ret(0,head), *p = &ret, *q; while(p->next){ if(p->next->next && p->next->val == p->next->next->val){ q = p->next->next; while(q && q->val == p->next->val) q = q->next; p->next = q; }else{ p = p->next; } } return ret.next; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。