class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode*p1=nullptr;
ListNode*p2=pHead;//定义p1为空指针,p2为开始节点
while(p2){//循环结束是p2为空
ListNode*temp=p2;//保存p2
p2=p2->next;//p2先走,防止反转后失去下一个节点
temp->next=p1;//原p2的位置反转
p1=temp;//反转后p1去原p2的位置
}
return p1;//最后返回的是p1,因为p2为空了
}
};
class Solution {
public:
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
ListNode* reverseBetween(ListNode* head, int m, int n) {
// write code here
ListNode* res = new ListNode(-1);//建立头节点,不然首节点反转的话返回节点得重新赋值
res->next = head;
//前序节点
ListNode* pre = res;//在头节点
//当前节点
ListNode* cur = head;//在首节点
//找到m
for(int i = 1; i < m; i++){//令cur到链表的m位置,pre到链表的m-1位置
pre = cur;
cur = cur->next;
}
//从m反转到n(反转一次相当于m和m+1反转)
for(int i = m; i < n; i++){//反转方式为(以m与m+1节点反转为例)
ListNode* temp = cur->next;//保存m+1位置节点
cur->next = temp->next;//m+1节点的下一个节点连到m节点后面
temp->next = pre->next;//m位置的节点连到原m+1节点后面
pre->next = temp;//最后把原m+1连到m-1节点后面,完成相邻反转
}//循环
//返回去掉表头
return res->next;
}
};
class Solution {
public:
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* reverse(ListNode* head, int m, int n) {
ListNode* phead = new ListNode(0);
phead->next = head;
ListNode* p1 = phead;
ListNode* p2 = head;
for (int i = 1; i < m; i++) {
p1 = p2;
p2 = p2->next;
}
for (int i = m; i < n; i++) {
ListNode* temp = p2->next;
p2->next = p2->next->next;
temp->next = p1->next;
p1->next = temp;
}
return phead->next;
}//和前面带位置反转一样
ListNode* reverseKGroup(ListNode* head, int k) {
if (!head)return nullptr;
// write code here
ListNode* point = head;
//双指针,记录反转区间边界节点的坐标
int j = 1;
int i = 1;
int num=1;
//记录链表节点的数目
while (point->next) {
point=point->next;
num++;
}
for(int i=1;i<=num;i++){
if (i % k == 0) {//到k,2k,3k节点时停
head = reverse(head, j, i);//反转区间,注意head需要赋值,因为反转时原首节点变化了
j = i + 1;//左边界更新
}
}
return head;
}
};
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode*p1=pHead1;
ListNode*p2=pHead2;
ListNode*point=new ListNode(0);//新建头节点
ListNode*p=point;
while(p1&&p2){//都不为空时,一个为空说明要结束比较了
if(p1->val>p2->val){
p->next=p2;//后面接小的
p2=p2->next;//更新比较节点
p=p->next;//更新位置节点
}
else{
p->next=p1;
p1=p1->next;
p=p->next;
}
}
//不为空的直接复制
if(!p1){
p->next=p2;
}
if(!p2){
p->next=p1;
}
return point->next;
}
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
ListNode* point = new ListNode(0);
ListNode* p = point;
while (p1 && p2) {
if (p1->val > p2->val) {
p->next = p2;
p2 = p2->next;
p = p->next;
} else {
p->next = p1;
p1 = p1->next;
p = p->next;
}
}
if (!p1) {
p->next = p2;
}
if (!p2) {
p->next = p1;
}
return point->next;
}
//利用归并排序思想,将容器内二分到只有一个链表,然后再拼接,这样后面拼接的都是有序链表
ListNode* merge(vector<ListNode*>& lists, int l, int r) {//返回一个链表节点
if (l > r)return nullptr;
else if (l == r)return lists[l];//当分到只有一个链表时可以停止了
int mid = (l + r) / 2;
ListNode* p1 = merge(lists, l, mid);//记录分开的链表
ListNode* p2 = merge(lists, mid + 1, r);
return Merge(p1, p2);//合并
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
return merge(lists, 0, lists.size() - 1);//返回最后合并的链表
}
bool hasCycle(ListNode *head) {
//先判断链表为空的情况
if(head == NULL)
return false;
//快慢双指针
ListNode* fast = head;
ListNode* slow = head;
//如果没环快指针会先到链表尾
while(fast != NULL && fast->next != NULL){ //如果循环条件改为fast==slow的话,开始节点就相等了
//快指针移动两步
fast = fast->next->next; //条件判断就是fast->next存在才行
//慢指针移动一步
slow = slow->next;
//相遇则有环
if(fast == slow)
return true;
}
//到末尾则没有环
return false;
}
//判断有没有环,返回相遇的地方
ListNode* hasCycle(ListNode *head) {
//先判断链表为空的情况
if(head == NULL)
return NULL;
//快慢双指针
ListNode* fast = head;
ListNode* slow = head;
//如果没环快指针会先到链表尾
while(fast != NULL && fast->next != NULL){ //如果条件改为相等就需要开始走
//快指针移动两步
fast = fast->next->next;
//慢指针移动一步
slow = slow->next;
//相遇则有环
if(fast == slow)
//返回相遇的地方
return slow;
}
//到末尾则没有环
return NULL;
}
ListNode* EntryNodeOfLoop(ListNode* pHead) {
ListNode* slow = hasCycle(pHead);
//没有环
if(slow == NULL)
return NULL;
//快指针回到表头
ListNode* fast = pHead;
//再次相遇即是环入口
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return slow;
}
ListNode* FindKthToTail(ListNode* pHead, int k) {
ListNode* fast = pHead;
ListNode* slow = pHead;
//快指针先行k步
for(int i = 0; i < k; i++){
if(fast != NULL)
fast = fast->next;
//达不到k步说明链表过短,没有倒数k
else
return slow = NULL;
}
//快慢指针同步,快指针先到底,慢指针指向倒数第k个
while(fast != NULL){
fast = fast->next;
slow = slow->next;
}
return slow;
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
ListNode*phead=new ListNode(0);//删除的话,需要头节点
phead->next=head;
ListNode*p1=phead;
ListNode*p2=phead;
for(int i=1;i<=n;i++){
p2=p2->next;
}
p2=p2->next;//多走一步,因为需要删除
while(p2){
p2=p2->next;
p1=p1->next;
}
p1->next=p1->next->next;
return phead->next;
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(!pHead1||!pHead2)return nullptr;
ListNode*quick=pHead1;
ListNode*slow=pHead2;
int res=0;
while(quick!=slow){
if(quick->next){
quick=quick->next;
}
else{
quick=pHead2;
res++;//指示变量,记录循环找的次数
}
if(slow->next){
slow=slow->next;
}
else{
slow=pHead1;
}
if(res==2){
return nullptr;
}
}
return quick;
}
bool isPail(ListNode* head) {
vector<int> nums;
//将链表元素取出一次放入数组
while(head != NULL){
nums.push_back(head->val);
head = head->next;
}
vector<int> temp = nums;
//准备一个数组承接翻转之后的数组
reverse(temp.begin(), temp.end());
for(int i = 0; i < nums.size(); i++){
//正向遍历与反向遍历相同
if(nums[i] != temp[i])
return false;
}
return true;
}
ListNode* oddEvenList(ListNode* head) {
// write code here
if(!head)return nullptr;//为空
ListNode*p1=head;//记录第一个奇节点
ListNode*p2=head->next;//记录第一个偶节点
ListNode*point=p2;//记录奇偶交界处
while(p2&&p2->next){//p2是快节点,因此用它来判断是否结束
p1->next=p2->next;//把偶节点的下一个节点(奇)接到上奇节点后
p1=p1->next;//更新奇节点
p2->next=p1->next;//新奇节点下一个接到原偶节点
p2=p2->next;//更新偶节点
}
p1->next=point;//奇偶连接
return head;
}
ListNode* deleteDuplicates(ListNode* head) {
//空链表
if(head == NULL)
return NULL;
//遍历指针
ListNode* cur = head;
//指针当前和下一位不为空
while(cur != NULL && cur->next != NULL){
//如果当前与下一位相等则忽略下一位
if(cur->val == cur->next->val)
cur->next = cur->next->next;
//否则指针正常遍历
else
cur = cur->next;
}
return head;
}
ListNode* deleteDuplicates(ListNode* head) {
//空链表
if(head == NULL)
return NULL;
ListNode* res = new ListNode(0);
//在链表前加一个表头
res->next = head;
ListNode* cur = res;
while(cur->next != NULL && cur->next->next != NULL){ //这个条件保证cur后面至少有两个节点
//遇到相邻两个节点值相同
if(cur->next->val == cur->next->next->val){
int temp = cur->next->val;
//将所有相同的都跳过
while (cur->next != NULL && cur->next->val == temp)
cur->next = cur->next->next;
}
else
cur = cur->next;
}
//返回时去掉表头
return res->next;
}