leetcode之旅 - Day1

目录

二分查找变种

 二进制转整数

链表内指定区间反转

链表前缀和暴力解法


二分查找变种

搜索旋转排序数组

思路:

此题主要是一个二分查找的变种考察,如果不考虑效率,可以直接使用顺序查找,但肯定不是面试官想要的结果,所以还得另辟蹊径。 如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序 ,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪一半了

 

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size()-1;
        while(left<=right)
        {
            int mid=left+right>>1;
            if(nums[mid]==target) return mid;
            else if(nums[mid]<nums[right])    //右半段有序
            {
                //如果target在有序区间范围内,则搜索有序半边,否则搜索无序
                if(nums[mid]<target&&target<=nums[right]) left=mid+1;
                else right=mid-1;
            }
            else    //左半段有序
            {
                if(nums[left]<=target&& target<nums[mid]) right=mid-1;
                else left=mid+1;
            }
        }
        return -1;
    }
};

 二进制转整数

二进制链表转整数

此题主要考察单链表操作,对链表进行遍历提取节点的值,在把该值化为十进制数即可
class Solution {
public:
    int getDecimalValue(ListNode* head) {
        int ans=0;
        while(head!=NULL)
        {
            ans=ans*2+head->val;
            head=head->next;
        }
        return ans;
    }
};

链表内指定区间反转

链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com)

思路:

此题主要考察单链表的反转操作,核心思路主要是借助临时头结点,找到需要翻转链表的前驱位置,然后将要翻转链表的节点摘下进行子链表的头部插入即可

即令m为头结点,将后面n-m个节点进行头插

 

举个栗子:

  1. 因为要把节点3插到1、2之间,所以令temp=节点3;
  2. 将结点2的指针连到4;
  3. 将结点3的指针连到2;
  4. 将结点1的指针连到3;

实现对m位置节点的头插,循环n-m次完成区间反转

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
         //加个表头
        ListNode* res = new ListNode(-1);
        res->next = head;
        //前序节点
        ListNode* pre = res; 
        //当前节点
        ListNode* cur = head; 
        //找到m
        for(int i = 1; i < m; i++){ 
            pre = cur;
            cur = cur->next;
        }
        //从m反转到n,头插n-m个
        for(int i = m; i < n; i++){ 
            ListNode* temp = cur->next;
            cur->next = temp->next;
            temp->next = pre->next;
            pre->next = temp;
        }
        //返回去掉表头
        return res->next; 
    }
};

反转链表_牛客题霸_牛客网 (nowcoder.com)

普通单链表反转

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
		ListNode* res=new ListNode(-1);
		res->next=pHead;
		ListNode* pre=res;

		while(pHead&&pHead->next!=nullptr)
		{
			ListNode* temp=pHead->next;
			pHead->next=temp->next;
			temp->next=pre->next;
			pre->next=temp;
		}
		return res->next;
	}
};

链表前缀和暴力解法

从链表中删去总和值为零的连续节点

思路:

借助链表考察前缀和的求解,要删去总和值为零的连续链表节点,只需维护每一个节点之前的所有和,此时如果该节点与前面节点的和 ( 即前缀和 ) 相加结果为 0 ,则该节点就可以抵消掉前面的节点,消除的时候就是把 next 指针指向和的下一个节点,然后在重复该过程,直到整个链表求解结束
class Solution {
public:
    ListNode* removeZeroSumSublists(ListNode* head) 
    {
        //初始化一个空结点,初始赋值为0,并且list的下一个next指针指向head
        ListNode* dummyhead = new ListNode(0, head);
        ListNode* cur = dummyhead;
        int sum = 0;
        while (cur != nullptr)
        {
            ListNode* search = cur->next;
            sum = 0;
            while (search != nullptr)
            {
                sum += search->val;
                if (sum == 0) cur->next = search->next;
                search = search->next;
            }
            cur = cur->next;
        }
        ListNode* ret = dummyhead->next;
        delete dummyhead;
        return ret;
    }
};

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黄同学LL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值