LeetCode--练习题(顺序表链表)

一、消失的数字

思路一: 

 

int missingNumber(int* nums, int numsSize)
{
    int x = 0;
    int i = 0;
    for(i=0;i<=numsSize;i++)
    {
        x^=i;
    }
    for(i=0;i<numsSize;i++)
    {
        x^= (*(nums+i));
    }
    return x;
}

思路二

int missingNumber(int* nums, int numsSize)
{
    int sum = 0;
    int i = 0;
    for(i=0;i<=numsSize;i++)
    {
        sum += i;
    }
    for(i=0;i<numsSize;i++)
    {
        sum -=nums[i];
    }
    return sum;
}

二、轮转数组

思路一 

因为时间复杂度太大,导致运行时间超载,不建议使用这个思路 

void rotate(int* nums, int numsSize, int k) {
    k = k%numsSize;
    for(k;k>0;k--)
    {
        int tmp = nums[numsSize-1];
        for(int i=numsSize-1;i>0;i--)
        {
            
            nums[i] = nums[i-1];
        }
        nums[0] = tmp;
    }
    printf("%s",nums);
}

思路二

时间复杂度O(n)空间复杂度O(n) 

void rotate(int* nums, int numsSize, int k) {
    k = k % numsSize;
    int newnums[numsSize];
    int j = 0;
    for(int tail = numsSize - k; tail <= numsSize - 1; tail++) {
        newnums[j] = nums[tail];
        j++;
    }
    for(int head = 0; head < numsSize - k; head++) {
        newnums[j] = nums[head];
        j++;
    }
    for(int i = 0; i < numsSize; i++) {
        nums[i]=newnums[i];
    }
}

思路三 

 时间复杂度O(n),空间复杂度O(1)

//逆置函数
void reverse(int* arr,int n)
{
    int left,right,tmp;
    left = 0;
    right = n-1;
    while(left<right)
    {
        tmp = arr[right];
        arr[right]=arr[left];
        arr[left] = tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numsSize, int k) 
{
    k = k%numsSize;//防止出现负数
    reverse(nums,numsSize-k);//先逆置前面的
    reverse(nums+numsSize-k,k);
    reverse(nums,numsSize);
}

三、删除有序数组的重复项

思路

int removeDuplicates(int* nums, int numsSize){
    int* p=nums;
    int* tail=nums;
    int tmp;
    int count=0;
    tmp=nums[0];
    for(int i=0;i<numsSize;i++)
    {
      if(tmp!=(*p))
      {
        tmp=(*p);
        tail++;
        (*tail)=tmp;
        count++;
      }
        p++;
    }
    // for(int j = 0;j<=count;j++)
    // {
    //     printf("%d",nums[j]);
    // }
    return count+1;
}

四、返回倒数第k个节点

思路一 

 时间复杂度O(n)空间复杂度O(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode list;
int kthToLast(struct ListNode* head, int k)
{
    list* p=head;
    list* pp=head;
    int count=0;
    while(p)
    {
        count++;
        p=p->next;
    }
    int end = count - k;
    while(end--)
    {
        pp=pp->next;
    }
    return pp->val;

}

思路二

时间复杂度O(n)空间复杂度O(1) 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode list;
int kthToLast(struct ListNode* head, int k)
{
    if(head==NULL)
    {
        return head;
    }
    list* n1,*n2,*n3;
    n1=NULL;
    n2=head;
    n3=head;
    //逆置
    while(n2)
    {
        n3=n3->next;
        n2->next=n1;
        n1=n2;
        n2=n3;
    }
    while(--k)
    {
        n1=n1->next;
    }
    return n1->val;
}

 五、链表的回文结构

思路很简单主要是对中间节点的寻找和对中间节点以后的链表进行逆置然后比较大小

下面的代码我就不写全就用函数调用来表示

class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        ListNode* mid=middleNode(A);//中间节点
        ListNode* rmid=reverseList(mid);//逆置
        while(A&&rmid)
        {
            if(A->val!=rmid->val)
            {
                return false;
            }
            A =A->next;
            rmid = rmid->next;
        }
        return true;
    }
};

 六、相交链表

思路 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode list;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
    list* pA=headA;
    list* pB=headB;
    int countA=1;
    int countB=1;    
    while(pA->next)
    {
        pA=pA->next;
        countA++;
    }
    while(pB->next)
    {
        pB=pB->next;
        countB++;
    }
    if(pA!=pB)
    {
        return NULL;
    }else{
        //判断谁大
    if(countA>=countB)
    {
        int a=countA-countB;
        while(a--)
        {
           headA=headA->next;
        }
        while(headA!=headB)
        {
            headA=headA->next;
            headB=headB->next;
        }
        return headA;
    }else
        {
        int b=countB-countA;
        while(b--)
        {
            headB=headB->next;
        }
        while(headA!=headB)
        {
            headA=headA->next;
            headB=headB->next;
        }
        return headA;
        }
    }         
}

 上面是我自己写的代码过于冗余,下面的会好很多

typedef struct ListNode list;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
    list* pA=headA;
    list* pB=headB;
    int countA=1;
    int countB=1;    
    while(pA->next)
    {
        pA=pA->next;
        countA++;
    }
    while(pB->next)
    {
        pB=pB->next;
        countB++;
    }
    if(pA!=pB)
    {
        return NULL;
    }
    int gap=abs(countA-countB);
    list* longList = headA;
    list* shortList = headB;
    if(countB>countA)
    {
        longList=headB;
        shortList=headA;
    }
    while(gap--)
    {
        longList=longList->next;
    }
    while(longList!=shortList)
    {
        longList=longList->next;
        shortList=shortList->next;
    }
    return longList;
}

七、环形链表

 

再使用快慢指针的时候一定要注意

  1.  栈溢出
  2. 是否为空节点
 typedef struct ListNode list;
bool hasCycle(struct ListNode *head) 
{
    list* fast,*slow;
    fast=slow=head;
    //单链表一个节点判断一下
    if(head==NULL||head->next==NULL)
    {
        return false;
    }
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(fast==slow)
        {
            return true;
        }
    }
    return false;
}

 八、环形链表②

 

 

typedef struct ListNode list;
struct ListNode *detectCycle(struct ListNode *head) {
    list*fast,*slow;
    fast=slow=head;
    if(head==NULL||head->next==NULL)
    {
        return NULL;
    }
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            break;
        }
    }
    if(slow==fast)
    {
        //如果不相等就一直循环
        while(head!=slow)
        {
            head=head->next;
            slow=slow->next;
        }
        //相等后跳出循环
        return head;
    }
    return NULL;
}

思考:如果slow走一步,fast走三步,一定会相遇吗?会不会错开

一定会相遇

九、随机链表的复制

步骤 

 ​​​​​​​

 

typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {
	Node* cur = head;
    //拷贝节点插入原节点的后面
    while(cur)
    {
        Node* copy = (Node*)malloc(sizeof(Node));
        copy->val = cur->val;

        //插入
        copy->next = cur->next;
        cur->next = copy;

        //迭代
        cur = cur->next->next;
    }

    //控制拷贝节点的random
    cur = head;
    while(cur)
    {
        Node* copy = cur->next;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;
        }
        //迭代
        cur = cur->next->next;
    }

    //把copy节点解下来,链接成新的链表
    Node* copyhead = NULL,*tail = NULL;
    cur = head;
    while(cur)
    {
        Node* copy = cur->next;
        Node* next = copy->next;
        //尾插
        if(tail == NULL)
        {
            copyhead = tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }
        cur->next =next;
        cur = next;
    }

    return copyhead;

}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值