目录
得到链表长度,从数组的最后一个位置开始存放链表元素,即得到逆置
在函数中使用数组,函数结束还要返回此数组地址,需要给这个数组动态分配内存int *res=(int *)malloc(size*sizeof(int));
876. 链表的中间结点
这道题简直就是为快慢指针量身定制的
双指针法
- 序列:1-2-3-4-5
- slow:1-2-3,到3时fast->next为空结束循环(巧了刚好是题目要求的位置)
- fast:1-3-5
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
if(!head) return NULL;
struct ListNode *slow=head,*fast=head;
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
常规法
- 序列:1-2-3-4-5
- count:0-1-2-3-4
- count:4/2
- count--:2-1-0
- head此时指向3
- (数字有点纠结因为想从1开始,但是其实前后统一就可以,而且刚好为0时退出循环)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
int count=0;
struct ListNode *p=head;
while(p){
p=p->next;
count++;
}
count=count/2;
while(count--){head=head->next;}
return head;
}
1290. 二进制链表转整数
-
左移一位*2:位运算的方法真是绝妙
-
左移 1 位后最低位为零;val 为 0 或 1 ( val = 0x00000000 或者 0x00000001 );res 和 val 进行“或”的位运算,只会改变 res 的最低位,这里的 或 改成 加法 ,结果也是一样的
-
C语言问题,在位运算中,操作数每右移一位,其结果相当于什么?若左移1位,其结果相当于什么?
答案:
右移,除以2
左移,乘以2
比如5,5的二进制表示是101那么右移一位之后是10就是2了,是整除的,左移的话就是在后面补一个零,相当于是乘以二,那么变成了1010,十进制是10。 - 5 二进制:101
- 左移1位:1010=10(左移乘二)
- 右移一位:10=2(右移除二,整除)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int getDecimalValue(struct ListNode* head){
int res=0;
for ( ; head; head = head->next)
res=(res<<1)+head->val;
return res;
}
剑指 Offer 06. 从尾到头打印链表
### 解题思路
- 执行用时:12 ms, 在所有 C 提交中击败了43.90的用户
- 内存消耗:6.8 MB, 在所有 C 提交中击败了59.83%的用户
-
得到链表长度,从数组的最后一个位置开始存放链表元素,即得到逆置
-
在函数中使用数组,函数结束还要返回此数组地址,需要给这个数组动态分配内存int *res=(int *)malloc(size*sizeof(int));
- 传入的参数如果是指针,注意赋值以免指向不安全内存
### 代码
```c
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* reversePrint(struct ListNode* head, int* returnSize){
if(head==NULL){
*returnSize=0;
return NULL;
} //链表空,返回空,返回长度0
struct ListNode *p=head;
int size=0;
while(p){//得到链表长度,注意从0开始
p=p->next;
size++;
}
int *res=(int *)malloc(size*sizeof(int));
//res作为一个指针在函数结束会被释放,所以必须malloc出来,才能作为返回值
// for(int i=0;i<size;i++){
// res[size-1-i]=head->val;
// head=head->next;
// }
for(int i=size-1;i>=0;i--){
res[i]=head->val;
head=head->next;
}
*returnSize=size;
//没有此句的报错,说明未被定义的returnSize指针指向了不安全内存
return res;
}
剑指 Offer 18. 删除链表的节点(W)
解题思路
执行用时:4 ms, 在所有 C 提交中击败了96.69%的用户
内存消耗:6 MB, 在所有 C 提交中击败了18.72%的用户
- 处理链表空
- 处理链头就是待删
- 处理待删在链中
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteNode(struct ListNode* head, int val){
if(!head) return NULL;
if(head->val==val){head=head->next;}
struct ListNode *p=head;
while(p&&p->next){
if(p->next->val==val) {
p->next=p->next->next;
break;
}
p=p->next;
}
return head;
}