输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
思想:借用栈先进后出的特性
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> result;
stack<int> arr;
ListNode* p=head;
if(p==NULL)
{
return result;
}
while(p!=NULL)
{
arr.push(p->val);
p=p->next;
}
int len=arr.size();
for(size_t i=0;i<len;i++)
{
result.push_back(arr.top());
arr.pop();
}
return result;
}
};
convert-sorted-list-to-binary-search-tree
给定元素按升序排序的单个链接列表,将其转换为高度平衡BST。
思想:
这道题是要求把有序链表转为二叉搜索树,和之前那道Convert Sorted Array to Binary Search Tree思路完全一样,只不过是操作的数据类型有所差别,一个是数组,一个是链表。数组方便就方便在可以通过index直接访问任意一个元素,而链表不行。由于二分查找法每次需要找到中点,而链表的查找中间点可以通过快慢指针来操作。找到中点后,要以中点的值建立一个数的根节点,然后需要把原链表断开,分为前后两个链表,都不能包含原中节点,然后再分别对这两个链表递归调用原函数,分别连上左右子节点即可。
class Solution {
public:
TreeNode *sortedListToBST(ListNode *head) {
return BST(head,NULL);
}
TreeNode *BST(ListNode *head,ListNode *tail)
{
if(head == tail)
return NULL;
ListNode *s = head;
ListNode *f = head;
while(f!=tail && f->next!=tail)
{
f = f->next;
s = s->next;
if(f!=NULL)
{
f=f->next;
}
}
TreeNode *root = new TreeNode(s->val);
root->left = BST(head,s);
root->right = BST(s->next,tail);
return root;
}
};
给定一个链表和一个值x,对其进行分区,使所有小于x的节点都位于大于或等于x的节点之前。您应该保留两个分区中每个节点的原始相对顺序。例如,给定1->4->3->2->5->2和x=3,返回1->2->2->4->3->5.
思想:
由题意可知:本题要比较大小并排序,所有需要定义一个临时节点遍历链表。(我定义了cur)
要求不改变相对位置的排序,我们利用合并链表的方法,定义两个链表,如果当前值比x小,就将该节点连接到链表1,反之则连接到链表2后边。当链表遍历完结后,将链表1连接到链表2后面,就可以实现要求
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(!head||!head->next) return head;
ListNode *res1=new ListNode(0);ListNode *p1=res1;
ListNode *res2=new ListNode(0);ListNode *p2=res2;
ListNode *cur=head;
while(cur){
if(cur->val< x) {p1->next=cur;p1=p1->next;}
else {p2->next=cur;p2=p2->next;}
cur=cur->next;
}
p2->next=NULL;
p1->next=res2->next;
return res1->next;
}
};
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given1->2->3->4->5->NULLand k =2,
return4->5->1->2->3->NULL.
旋转链表:
思路:先求出链表的长度,然后将链表连接成一个环。
由于K可能大于链表长度,所以要将k进行取模运算。
连接成环以后,再朝前走len-k步,走到给定K位置的前一个位置处,将其下一个节点设置成头结点,然后将其断开。就是给定要求的链表了。
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(head==nullptr||k==0)
return head;
int len=1;
ListNode *p=head;
while(p->next){
//遍历一遍,求出链表长度
len++;
p=p->next;
}
k=len-k%len;
p->next=head;//首尾相连
for(int step=0;step<k;step++){
p=p->next;//接着往后跑
}
head=p->next;//新的首节点
p->next=nullptr;//断开环
return head;
}
};
删除倒数第K个节点
定义两个指针,一个指针,一个慢指针,让快指针先走K-1步,然后快慢指针一起走。当快指针走到结尾时,慢指针刚好走到倒数第K个节点。删除即可。注意考虑删除的是头结点(如果fast先走时,走到尾节点时)
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
if(head==NULL)
{
return NULL;
}
ListNode* fast=head;
ListNode* slow=head;
while(n--)
{
fast=fast->next;
}
if(fast==NULL)
{
return head->next;
}
while(fast->next!=NULL)
{
slow=slow->next;
fast=fast->next;
}
ListNode*tmp=slow->next;
slow->next=slow->next->next;
delete tmp;
tmp=NULL;
return head;
}
};