c++/c算法和数据结构面试整理

1.排序:我都可以代码实现询问面试官哪个算法需要展开?快排的优化1.简述快排的过程.快排就是:每次找到一个基准值, 然后将数组分成两部分,前半边都是小于基准值的, 后半边都是大于基准值的, 对基准值两边分别进行快排操作, 这样我们就形成了一个递归的过程.2.时间复杂度:最好:O(nlogn)最坏:O(n2) 平均:o(nlogn)parttion过程需要o(n);将数组分成两部分, 每部分n/2;n/ 2->n/4->…->1个节点.可分log2(n)层, 像第二层
摘要由CSDN通过智能技术生成

文章目录

一.排序:

排序

二.链表

往链表的末尾添加元素

ListNode *AddToTail(ListNode *pHead, int value) {
    ListNode *pNew = new ListNode();
    pNew->val = value;
    pNew->next = nullptr;
    if (pHead == nullptr) {
        return pNew;
    } else {
        ListNode *p = pHead;
        while(p->next) {
            p = p->next;
        }
        p->next = pNew;
    }
    return pHead;
}

从尾到头打印链表

void  PrintListReversingly(ListNode *head) {
	std::stack<int> s;
	ListNode *p = head;
	while(p != nullptr) {
		s.push(p->val);
		p = p->next;
	}	
	while(!s.empty()) {
		printf("%d\t", s.top());
		s.pop();
	}
}

合并两个有序链表

class Solution {
   
public:
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
   
		if(l1 == NULL) return l2;
		if(l2 == NULL) return l1;
		if(l1->val < l2->val) {
   
			l1->next=mergeTwoLists(l1->next,l2);
			return l1;
		} else {
   
			l2->next=mergeTwoLists(l1,l2->next);
			return l2;
		}
	}
};

反转链表

struct ListNode* ReverseList(struct ListNode* pHead ) {
   
    // write code here
    if(pHead == NULL || pHead->next == NULL) return pHead;
    struct ListNode* p = ReverseList(pHead->next);
    pHead->next->next = pHead;
    pHead->next = NULL;
    return p;
}
class Solution {
   
public:
    ListNode* ReverseList(ListNode* pHead) {
   
        ListNode *pre = nullptr, *cur = pHead, *last;
        while(cur) {
   
            last = cur->next;
            cur->next = pre;
            pre = cur;
            cur = last;
        }
        return pre;
    }
};

判断链表是否是回文链表

	class Solution {
   
public:
    ListNode *reverse(ListNode *head) {
   
        ListNode *p = head, *q, *pre = NULL;
        while(p){
   
            q = p->next;
            p->next = pre;
            pre = p;
            p = q;
        }
        return pre;
    }
    bool isPalindrome(ListNode* head) {
   
        ListNode *fast = head, *last = head;
        while (fast && fast->next) {
   
            last = last->next;
            fast = fast->next;
            fast = fast->next;
        }
        if (fast) last = last->next;
        last = reverse(last);
        fast = head;
        while(last && fast) {
   
            if (last->val != fast->val) return false;
            fast = fast->next;
            last = last->next;
        }
        return true;    
    }
};

链表相交

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
   
    struct ListNode *p = headA, *q = headB;
   while (p != q) {
   
        p = p ?  p ->next : headB;
        q = q ?  q ->next :  headA;
    } 
    return p;
}

链表的环

在这里插入图片描述快指针p, 慢指针q;
环的起始位置为o, 相遇位置为x, 从起点到环的起始位置长la, 环长lc;1.la < lc
当慢指针q到环的起始位置o时,慢指针q走了la长,快指针p已经走了2*la,此时快指针距离起始位置o还有lb, 得la + lb = lc,现在两者都在环上, 接下来的运动轨迹,可以视为追击问题, 每次运动,快指针p与慢指针q的距离-1,相遇需运动lb次,此时慢指针q走了lb, 在往后走la步可到环的起点(注:la + lb = lc);相遇后让快指针p到起点࿰

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值