文章目录
1.数组oj
2.链表oj
文章内容
1.数组oj
1. 原地移除数组中所有的元素值为val,要求时间复杂度为O(N),空间复杂度为O(1)。力扣
int removeElement(int* nums, int numsSize, int val){int k = numsSize;int a = 0;int b = 0;while(b<k){if(nums[b] != val){nums[a] = nums[b];a++;b++;}else{b++;}}return a;}
2. 删除排序数组中的重复项。力扣
int removeDuplicates(int* nums, int numsSize){int src = 1;
int dest = 0;while(src < numsSize)
{
if(nums[src] == nums[dest])
{
src++;
}
else
{dest++;nums[dest] = nums[src] ;src++;
}}return dest+1;
}
3. 合并两个有序数组。力扣
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){int end1 = m-1;int end2 = n-1;while(end1>=0 && end2>=0){if(nums1[end1] > nums2[end2]){nums1[nums1Size-1] = nums1[end1];end1--;nums1Size--;}else{nums1[nums1Size-1] = nums2[end2];end2--;nums1Size--;}}while(end2>=0){nums1[nums1Size-1] = nums2[end2];end2--;nums1Size--;}//return nums1;
}
2.链表oj
1. 删除链表中等于给定值 val 的所有结点。力扣
struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode* prve = NULL;
struct ListNode* cur = head;while(cur)
{if(cur->val == val) {if(cur == head){head = cur->next;free(cur);cur = head;}else{prve->next = cur->next;free(cur);cur=prve->next;}}else{prve = cur;cur = cur->next;}}return head;
}
2. 反转一个单链表。力扣
方法一:
struct ListNode* reverseList(struct ListNode* head)
{struct ListNode* newhead = NULL;
struct ListNode* cur = head;while(cur)
{struct ListNode* after = cur->next;//头插
cur->next = newhead;newhead = cur;
cur = after;
}return newhead;}
方法二:
思维图
struct ListNode* reverseList(struct ListNode* head){struct ListNode* n1,* n2,* n3;n1 = NULL;n2 = head;if(n2){n3 = n2->next;}while(n2){n2->next = n1;//往后走n1 = n2;n2 = n3;if(n3){n3 = n3->next;}}return n1;
}
3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则
返回第二个中间结点。力扣
4. 输入一个链表,输出该链表中倒数第k个结点。链表中倒数第k个结点_牛客题霸_牛客网
本题思路与上一题类似。
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code here
struct ListNode* fast = pListHead;
struct ListNode* slow = pListHead;while(k--)
{if(fast == NULL)
{return NULL;
}fast = fast->next;
}while(fast)
{
slow=slow->next;
fast=fast->next;
}return slow;}
5. 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有
结点组成的。力扣
6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结
点之前 。链表分割_牛客题霸_牛客网
class Partition {
public:ListNode* partition(ListNode* pHead, int x) {// write code herestruct ListNode* phead = pHead;struct ListNode * lesshead,*lesstail,*greaterhead,*greatertail;lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));greaterhead = greatertail = (struct ListNode*)malloc(sizeof(struct ListNode));while(phead){if(phead ->val < x){lesstail ->next = phead;lesstail = lesstail->next;}else{greatertail ->next = phead;greatertail = greatertail->next;}phead= phead->next;}lesstail->next = greaterhead->next;free(greaterhead);struct ListNode* head = lesshead->next;free(lesshead);greatertail->next = NULL;return head;}
};
7. 链表的回文结构。链表的回文结构_牛客题霸_牛客网
本题需要用到查找中间节点,和逆置链表,这两项,上述内容都有
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head, * fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}struct ListNode* reverseList(struct ListNode* head)
{struct ListNode* newnode = NULL;struct ListNode* cur = head;while (cur){struct ListNode* after = cur->next;//头插cur->next = newnode;newnode = cur;cur = after;}return newnode;}class PalindromeList {
public:bool chkPalindrome(ListNode* head){// write code herestruct ListNode * mid = middleNode(head);struct ListNode * rmid = reverseList(mid);while(rmid && head){if(rmid->val != head->val){return false;}rmid = rmid->next;head= head->next;}return true;}};
8. 输入两个链表,找出它们的第一个公共结点。力扣
故本题的思路就是先计算出两个链表的长度,之后让长的链表先走差值步。之后两个链表一起走,如果两个链表遍历到最后都没有公共节点,那么说明两个链表不相交。
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* cura = headA,*curb = headB;int len1 = 0;int len2 = 0;while(cura){cura = cura->next;++len1;}while(curb){curb = curb->next;++len2;}int gab = abs(len1-len2);if(len1>len2){while(gab--){headA = headA ->next;}while(headA != headB && headA && headB){headA = headA->next;headB = headB->next;}if(headA == NULL){return NULL;}return headA;}else{while(gab--){headB = headB ->next;}while(headA != headB && headA && headB){headA = headA->next;headB = headB->next;}if(headA == NULL){return NULL;}return headA; }}
9. 给定一个链表,判断链表中是否有环。力扣
这到题的思路还是用快慢指针的思想来,快指针走两步,慢指针走一步,如果有环,快指针是回追上慢指针的。
bool hasCycle(struct ListNode *head) {struct ListNode* slow = head,*fast = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(slow == fast){return true;}}return false;
}
10. 给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULL力扣
快指针每次走两步,满指针每次走一步,每次差1步,当链表中有环,快指针肯定能追上满指针
这是为什么呢?
快指针走其他步呢?
有了以上的基础性分析,我们接下来再进行分析:
上图第一句话是 “右侧分析是典型的错误”!!!
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* slow = head ,*fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast){struct ListNode* meet = slow;while(head != meet){meet = meet->next;head = head->next;}return meet;}} return NULL;
}