0
点赞
收藏
分享

微信扫一扫

C++刷题之旅(50)

yongxinz 2022-04-05 阅读 68
c++leetcode

LeetCode算法入门(第五十天)

二分查找

153.寻找旋转排序数组中的最小值

在这里插入图片描述
题目中的旋转更像是将数组看成首尾相连的,然后移动,故此数组总有一部分是有序的。
如果中间值大于右边的值,说明原先右边大的值已经旋转到了左边,此时应在右边区间找最小值;
同理。

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;                
        while (left < right) {                      
            int mid = left + (right - left) / 2;    
            if (nums[mid] > nums[right]) {          /* 中值 > 右值,最小值在右半边,收缩左边界 */ 
                left = mid + 1;                     /* 因为中值 > 右值,中值肯定不是最小值,左边界可以跨过mid */ 
            } else if (nums[mid] < nums[right]) {   /* 明确中值 < 右值,最小值在左半边,收缩右边界 */ 
                right = mid;                        /* 因为中值 < 右值,中值也可能是最小值,右边界只能取到mid处 */ 
            }
        }
        return nums[left];     
    }
};




162.寻找峰值

在这里插入图片描述

因为峰值是严格大于它左右的元素,如果存在左右相邻的元素大于当前值,说明当前值不是峰值,转而判断那个大的元素的左右值。

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int n = nums.size();
        if(n == 1) return 0;

        // 先特判两边情况
        if(nums[0] > nums[1]) return 0;
        if(nums[n - 1] > nums[n - 2]) return n - 1;

        int l = 0, r = n - 1;
        while(l <= r) {
            int mid = (l + r) / 2;

            // 当前为峰值
            if(mid >= 1 && mid < n - 1 && nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) {
                return mid;
            } else if(mid >= 1 && nums[mid] < nums[mid - 1]) {
                // 峰值在 mid 左侧
                r = mid - 1;
            } else if(mid < n - 1 && nums[mid] < nums[mid + 1]) {
                // 峰值在 mid 右侧
                l = mid + 1;
            }
        }
        return -1;
    }
};


双指针

82.删除排序链表中的重复元素Ⅱ

在这里插入图片描述
正常的链表遍历,然后判断两个节点的值,但是当连续出现重复元素,需要在删除节点前需要记录
,然后不断的从链表中移除元素值相同的节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(!head){
            return head;
        }

        ListNode* dummy = new ListNode(0, head);

        ListNode* pre = dummy;   //哑结点,pre->next指向头节点
        while(pre->next && pre->next->next){
            if(pre->next->val == pre->next->next->val){
                int x = pre->next->val;  //当两个节点值相同时,删除前先记录节点值
                while(pre->next && pre->next->val == x){
                    pre->next = pre->next->next;  //更新节点
                }
            }
            else{
                pre = pre->next;
            }
        }
        return dummy->next;
    }
};

15.三数之和

在这里插入图片描述
因为数组中有重复元素,所以可能存在多组相同的解,因为需要额外判断跳过重复的解。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());  //sort默认升序排列

        for(int i = 0; i < nums.size(); i++){
            if(nums[i] > 0)   //若排序后第一个元素大于0,则不可能三树之和为0
                return result;
            
            if(i > 0 && nums[i] == nums[i-1]){   //跳过重复元素
                continue;
            }
            int left = i + 1;
            int right = nums.size() - 1;
            while(right >left){
                if(nums[i] + nums[right] + nums[left] > 0){
                    right--;
                }
                else if(nums[i] + nums[right] + nums[left] < 0){
                    left++;
                }
                else{
                    result.push_back(vector<int>{nums[i] , nums[left] , nums[right]});  //返回的结果为一个三元组 这里要要强转一下
                    while(right > left && nums[right] == nums[right - 1])  //跳过重复元素
                        right--;
                    while(right > left && nums[left] == nums[left + 1])  //跳过重复元素
                        left++;

                    //找到一组后,左右指针都需收缩
                    right--;  
                    left++;
                }
                    
            } 
        }

        return result;
    }
};
举报

相关推荐

C++刷题之旅(40)

C++刷题之旅(7)

C++刷题之旅(61)动态规划

C++刷题之旅(62)动态规划

C++刷题 -- 链表

HQL刷题 50道

C++刷题错误集锦

0 条评论