两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *new1=nullptr;
ListNode *currentpointer=new1;
int sum=0;
int carry=0;
if(l1==nullptr ) {//倒序,l1.vl==0并不是等于0;
new1=l2;
return new1;
}
if(l2==nullptr){
new1=l1;
return new1;
}
while(l1 != NULL || l2 != NULL){//C++中的NULL大写
sum=0;
sum+=carry;
if(l1!=nullptr){
sum+=l1->val;
l1=l1->next;
}
if(l2!=nullptr){
sum+=l2->val;
l2=l2->next;
}
if(sum>=10){
sum=sum-10;
carry=1;
}
else{
carry=0;
}
ListNode *node=new ListNode(sum);//空指针没有next;
if(currentpointer ==nullptr)
{
currentpointer=node;
new1=currentpointer;
}
else{
currentpointer->next=node;
currentpointer=currentpointer->next;
}
}
if(carry>0){
ListNode * node = new ListNode(1);//必须新建一个节点类型的指针
currentpointer->next=node;
}
return new1;
}
};
删除链表中倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *cur=head;
int length=0;
while(cur!=NULL)
{
length++;
cur=cur->next;
}
cur=head;
int l=length-n;
if(l==0){
head=head->next;
return head;
}
while(l>1)
{
cur=cur->next;
l--;
}
cur->next=cur->next->next;
return head;
}
};
进阶一遍遍历代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *kcur=head;
ListNode *mcur=head;
while(kcur->next!=NULL &&n>=1){
kcur=kcur->next;
n--;
}
if(n>=1){
head=head->next;
return head;
}
else{
while(kcur->next!=NULL){
kcur=kcur->next;
mcur=mcur->next;
}
mcur->next=mcur->next->next;
}
return head;
}
};
题目:删除排序链表的重复节点
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode *p =new ListNode(0);
p->next=head;
head=p;
ListNode*left,*right;
while(p->next){
left=p->next;
right=left;
while(right->next && right->next->val==left->val)
right=right->next;
if(left==right) p=p->next;
else p->next = right->next;
}
return head->next;
}
};
// 巧在了增加了一个头结点(0),这样头结点重复也可以删。三个指针,一个负责串联新链表,两个负责排除重复的节点。
题目旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
ListNode *cur=head;
if(head ==NULL) return head;//如果指针为空这一行就会爆
int length = 1;
while(cur->next!=NULL){//这样循环结束cur正好在尾结点
length++;
cur=cur->next;
}
int i=k%length;
i=length-i;
ListNode *tail =cur;
tail->next=head;//头结点和尾结点相连
cur=head;
while(i>=1){
if(i==1) tail=cur;//制造出新的尾结点
//这一块应当是i==2的时候才是尾节点,但是考虑到i初始值为1 ,只能如此赋值
cur=cur->next;
i--;
}
tail->next=NULL;
return cur;
}
};
分割链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode *smallist =new ListNode(0);
ListNode *biglist =new ListNode(0);
ListNode * node =head,*smallhead=smallist,*bighead=biglist;
while(node){
if(node->val next=node;
smallist=node;
}
else {
biglist->next=node;
biglist=node;
}
node =node ->next;
}
smallist->next=bighead->next;
biglist->next=NULL;
ListNode * tmp =smallhead->next;
//delete smallhead;
// delete bighead;
//return smallhead->next;
return tmp;
}
};
两种写法竟然速度不一样,但是是常数级别的优化所以不需要考虑
题目:反转链表II
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode * left =head;
for(int i=0;inext;
}
ListNode *begin=left;
if(m!=1){
begin = begin->next;
}
ListNode *cur =begin;
ListNode *mid =cur->next;
for(int i=0;inext;
mid->next =cur;
cur=mid;
mid=temp;
if(mid == nullptr){
break;
}
}
begin->next =mid;
if(m!=1){
left->next =cur;
return head;
}
else{
return cur;
}
}
};
题目:有序链表转换二叉搜索树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
// 树一定会用到递归,根节点左右子树-》一层递归的功能,
// 返回值:树的根节点、
// 终止条件是:链表遍历到头了
// 快慢指针法、DSF
if(head == NULL ||head ->next==NULL){
return head ==NULL ? NULL : new TreeNode(head->val);
}
ListNode * pre =head ,* mid=head, *fast=head;
while(fast !=NULL && fast->next!=NULL){
pre=mid;
mid=mid->next;
fast=fast->next->next;
}
pre->next=NULL;//左链表尾部
TreeNode *root=new TreeNode(mid->val);
root->left= sortedListToBST(head);
root->right = sortedListToBST(mid->next);
return root;
}
};