next数组_Leetcode刷题——数组与矩阵3 + 链表1

中间有一段时间没有完全适应工作节奏,所以刷题和其他的一些计划也搁置了,以后争取每天都做少量题练手。

今天是数组的中等/难题+链表的简单题。

我个人的思路整理:(题目代码在后面)

d7c0926312af9a53aa053197f2c13610.png

8127f93603b8c3792d3cb389fcfa8e59.png

3a8b5254d2284a813ef1134ccc7ffdce.png

03c3962655d6ed15221d3d471ab2db7c.png

6762db40103f090982de2a36acba3189.png

1b7f0e21648a136e7f07dc4971c89dfa.png

a5e40f8f4e866a6b720622a8054e1f99.png

55b8402e82d6f19607f34f0b6967ec7a.png

LC16 最接近的三数之和 中等

给出含有n个整数的数组s,找出s中和加起来的和最接近给定的目标值的三个整数。返回这三个整数的和。你可以假设每个输入都只有唯一解。

   例如,给定的整数 S = {-1 2 1 -4}, 目标值 = 1.↵↵   最接近目标值的和为 2. (-1 + 2 + 1 = 2).
class Solution {public:    int threeSumClosest(vector<int> &num, int target) {        int res=0;        int d=INT_MAX;        sort(num.begin(),num.end());                for(int i=0;i            int left=i+1;            int right=num.size()-1;                        while(left                int sum=num[i]+num[left]+num[right];                if(d>abs(sum-target)){                    res=sum;                    d=abs(sum-target);                }                if(sum==target)                    return target;                else if(sum>target)                    right--;                else                    left++;            }        }        return res;    }};

LC31 下一个排列 中等

实现函数next permutation(下一个排列):将排列中的数字重新排列成字典序中的下一个更大的排列。将排列中的数字重新排列成字典序中的下一个更大的排列。

如果不存在这样的排列,则将其排列为字典序最小的排列(升序排列)

需要使用原地算法来解决这个问题,不能申请额外的内存空间

下面有机组样例,左边是输入的数据,右边是输出的答案

1,2,3→1,3,2
3,2,1→1,2,3
1,1,5→1,5,1

class Solution {public:    void nextPermutation(vector<int> &num) {    /*    * 目的:下一个排列    * 方法:    * 例如:1 2 3 7 6 5 1    * 1.从后往前找到不满足递增排序的点    * 2.如果不存在这样的点证明数组是非递增的,直接reverse,然后返回即可    * 3.如果找到,例如上例中的7,则重新从后往前寻找大于3的第一个数,即5    * 4.交换3和5的位置,然后将后面的数组升序排列,即可得到结果    */        int n = num.size();        if(n<=1) return;        int i = n-1;        while((i>0) && (num[i] <= num[i-1])){                i--;        }        if(i==0){            reverse(num.begin(), num.end());        }        else{            int j = num.size()-1;            while(num[j]<=num[i-1])                j--;            swap(num[i-1], num[j]);            sort(num.begin()+i,num.end()); //后面的全部排序        }      }};

LC80 删除数组中重复元素2 中等

继续思考题目"Remove Duplicates":

如果数组中元素最多允许重复两次呢?

例如:

给出有序数组 A =[1,1,1,2,2,3],

你给出的函数应该返回length =5,  A 变为[1,1,2,2,3]

class Solution {public:    int removeDuplicates(int A[], int n) {        if(n<=2) return n;        int index=2;        for(int i=2;i            if(A[i]!=A[index-2])               A[index++]=A[i];        }        return index;    }};

LC88 合并两个有序数组 简单

给出两个有序的整数数组A和B,请将数组B合并到数组A中,变成一个有序的数组

注意:可以假设A数组有足够的空间存放B数组的元素,A和B中初始的元素数目分别为m和n

class Solution {public:    void merge(int A[], int m, int B[], int n) {        //这就是归并排序中合拼的部分        //由于不让new新数组(会爆)        //所以将大的放在A数组的最右边 从右边往左边放        //如果A穷尽,把B元素依次放进A的前几个位置,如果B穷尽,正好结束。                //边界:有一个数组为空        if(m==0){            for (int i = 0; i < n; i++){                A[i] = B[i];            }        }        if(n==0) return;                //归并        int i = m-1;        int j = n-1;        int cnt = m+n-1;        while(i>=0 && j>=0){            if (A[i]>=B[j]){                 A[cnt]=A[i];                cnt--;                i--;            }            else{                A[cnt]=B[j];                cnt--;                j--;            }        }        //如果B先穷尽了,不要紧        //如果A先穷尽了        if (i==-1){            while(j>=0){                A[j] = B[j];                j--;            }        }    }};

LC128 最长连续子序列 困难

给定一个无序的整数类型数组,求最长的连续元素序列的长度。

例如:

给出的数组为[100, 4, 200, 1, 3, 2],

最长的连续元素序列为[1, 2, 3, 4]. 返回这个序列的长度:4

你需要给出时间复杂度在O(n)之内的算法

class Solution {public:    int longestConsecutive(vector<int>& nums) {        unordered_set<int> st;        for(int n: nums) st.insert(n);        int ans = 0;        for(int i: st){            // 假如一个数在哈希表中存在比他小的,那么它不是可以作为开头的数字            if(i != INT_MIN && st.count(i-1)){                continue;            }            // 开始计数            int cnt = 1;            while(i!=INT_MAX && st.count(i+1)){                cnt ++;                i++;            }            ans = max(ans, cnt);        }        return ans;    }};

LC141 环形链表 简单

判断给定的链表中是否有环

扩展:

你能给出不利用额外空间的解法么?

class Solution {public:    bool hasCycle(ListNode *head) {        //用一快一慢指针,开始两个指针都指向链表头部。        //慢指针每次向前走一步,快指针每次向前走两步。        //如果有环,则两个指针最终一定会相遇。这种方法无须额外的空间。        ListNode * fast = head;        ListNode * slow = head;        //务必注意判断链表空、链表尾!!!        while (fast != NULL && fast->next != NULL){            slow = slow->next;            fast = fast->next->next;            if (slow == fast) return true;            }        return false;    }};

LC83 删除链表中重复元素 简单

删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次

例如:

给出的链表为1->1->2,返回1->2.

给出的链表为1->1->2->3->3,返回1->2->3.

class Solution {public:    /**     *      * @param head ListNode类      * @return ListNode类     */    ListNode* deleteDuplicates(ListNode* head) {        // write code here        ListNode* p = head;        // 一定注意判空!判断是否是尾!        while(p!=NULL){            while( p->next !=NULL && p->val == p->next->val){ //如果相邻两元素相同                p->next = p->next->next; //那么就删除这个元素            }            p = p->next; //指针后移一位        }        return head;    }};

剑指25 合并两个有序链表 简单

将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。

/** * struct ListNode { *  int val; *  struct ListNode *next; * }; */class Solution {public:    /**     *      * @param l1 ListNode类      * @param l2 ListNode类      * @return ListNode类     */    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        // write code here        //每次选择剩下的节点中最小的,而最小的一定是链表1或者链表2剩下部分的第一个。        //用递归大法        if (l1 == NULL) return l2;        if (l2 == NULL) return l1;                ListNode* head; //建立一个新链表的头结点            if (l1-> val < l2-> val){            head = l1;            head-> next = mergeTwoLists(l1->next, l2);        }        else{            head = l2;            head-> next = mergeTwoLists(l1, l2->next);        }        return head;    }};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值