范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

数据结构与算法链表

  链表
  关于单链表,比较特殊,在面试中,要时刻注意时间复杂度和额外空间复杂度的问题
  所以在笔试中,额外空间的应用无所谓,能做到即可,可以使用数组作为额外空间来使用
  而在面试中要注意把额外空间复杂度降到最小,所以用克隆的方式来代替额外空间
  这样子可以用不多的几个变量来确定关系,而位置的关系是通过克隆的位置关系来去确定的,这样的好处是让复杂度变低的同时还达到很好的效果桶排序
  基数排序:分别按照个十百为先分别排序,然后再往上排序,对于每一位都是已经排好序,虽然不用进行比较,但是花费的空间和时间 比较多基本稳定
  在排完序之后还保持着排序前的基本序列,在班级中按照成绩排,相同的排序按照学号前后综合排序
  在小样本的时候采用一种排序方式,大样本的时候采用另一种,让整体复杂度减小哈希表
  无序的,但有序表的key是有序的
  增删改查的复杂度都是常数,但是这个常数可能比较大
  unordermap,unordertree
  快慢指针求回文
  也可以申请栈,将每个数遍历后都放进栈里面去,然后依次弹出,比较
  可以采用快慢指针的方式,但是将头结点的下一位做慢指针,可以解决奇数和偶数问题
  随机哈希表的设置
  设置一个哈希表,将每个数的next和rand都放进哈希表里,第一次遍历老链表就是放进哈希表,第二次是根据哈希表里的next和rand,设置新链表的next和rand
  直接插入克隆结点在当前结点后面,这样的话就不用在哈希表里设置next了,然后在遍历的时候设置一下边界,一对对遍历,存入rand即可,克隆节点的rand就是原本节点rand的克隆节点
  有环链表
  可以申请哈希表额外空间,记录每个遍历后的结点,第一次重复访问到的节点就就是环的开头
  快慢指针:一开始都在head,慢指针一次走一步,快指针一次走两步,会在环里相遇,相遇后,快指针回到head,快慢指针同时走,都走一步,最终会在环的开始节点相遇无环链表
  判断两条链表是否在同一地址,即最后节点是否相同,因为当两条单链表有相交时,相交部分一定是相同的,next指针是不会断的。
  判断最后节点相同时即可判断出他们相交
  让长链表先走x 步,x为二者差值,然后二者同时走,一定会在相交节点相遇cur1 = n>0 ? head1 : head2//谁长,谁的头是head1 cur2 = cur1 == head1 ? head2 : head1 //谁短,谁的头是cur2
  重定位长短
  如果是相同环,则把终止节点设置为俩链表入环节点,其余按照无环链表操作,如果不同环,从loop 1开始,如果遇得到loop2,则是不同入环节点,返回谁都可以,但如果没有,则不相交
  合并k 个已排序链表
  思路:多个指针,有限几个变量,采用merge方法,拆分出左右两组链表,然后进行合并,大化小step 1:从链表数组的首和尾开始,每次划分从中间开始划分,划分成两半,得到左边n/2n/2n/2个链表和右边n/2n/2n/2个链表。step 2:继续不断递归划分,直到每部分链表数为1.step 3:将划分好的相邻两部分链表,按照两个有序链表合并的方式合并,合并好的两部分继续往上合并,直到最终合并成一个链表。class Solution { public:     ListNode *Merge2(ListNode *phead1, ListNode *phead2){         if(phead1 == NULL) return phead2;         if(phead2 == NULL) return phead1;         ListNode *head = new ListNode(0);         ListNode *cur = head;         while(phead1 && phead2){             if(phead1->val > phead2->val){                 cur->next = phead2;                 phead2 = phead2->next;             }             else{                 cur->next = phead1;                 phead1 = phead1->next;             }             cur = cur->next;         }          if(phead1) cur->next = phead1;         else cur->next = phead2;         return head->next;     }     ListNode *pideMerge(vector &lists, int left, int right){         if(left > right) return NULL;         else if (left == right) return lists[left];         int mid = (left + right) / 2;         return Merge2(pideMerge(lists, left, mid), pideMerge(lists, mid+1, right));     }      ListNode *mergeKLists(vector &lists) {         return pideMerge(lists, 0, lists.size() - 1);     } }; 链表中环的入口节点可以采用哈希表,放进去的节点遇到重复的第一个就是入环节点快慢指针:快指针走两步,慢指针走一步,当快慢指针相遇时,快指针返回起点,快慢指针一起走,都是走一步,再次相遇的节点就是入环节点class Solution { public:     ListNode* EntryNodeOfLoop(ListNode* pHead) {         if(pHead == NULL ) return NULL;         ListNode *slow = pHead;         ListNode *fast = pHead;                  while(fast != NULL && fast->next != NULL){             slow = slow->next;             fast = fast->next->next;             if(slow == fast)                 break;         }         if(fast == NULL || fast->next == NULL)             return NULL;         fast = pHead;         while(fast != slow){             fast = fast->next;             slow = slow->next;         }         return slow;     } }; 链表中倒数最后k个结点两次遍历的方法,先统计总长,然后n-k次遍历找到可以快慢指针,快指针先走k步,然后和慢指针一起走class Solution { public:    ListNode* FindKthToTail(ListNode* pHead, int k) {         // write code here         while(pHead == NULL) return NULL;         ListNode *fast = pHead;         ListNode *slow = pHead;         for(int i=0; inext;                      }         while(fast != NULL ){             slow = slow->next;             fast = fast->next;         }         return slow;      } }; 删除链表的倒数第n个结点 class Solution {   public:         ListNode* removeNthFromEnd(ListNode* head, int n) {             //添加表             ListNode* res = new ListNode(-1);             res->next = head;             //当前节点             ListNode* cur = head;             //前序节点             ListNode* pre = res;             ListNode* fast = head;             //快指针先行n步             while (n--)                 fast = fast->next;             while (fast != NULL) {                 fast = fast->next;                 pre = cur;                 cur = cur->next;             }             //删除该位置的节点             pre->next = cur->next;             //返回去掉头             return res->next;         } }; 两个链表的第一个公共结点循环遍历两个链表,迟早会相遇public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {         ListNode l1 = pHead1, l2 = pHead2;         while(l1 != l2){             l1 = (l1==null)?pHead2:l1.next;             l2 = (l2==null)?pHead1:l2.next;         }         return l1;     } 额外空间的,所有都存进去,看是否有相同的双指针,先走差值步,然后同时遍历,第一个相同的就是公共结点
  链表相加采用反转链表的方式class Solution { public:     ListNode *reverselist(ListNode *phead){         if(phead == NULL) return phead;         ListNode *cur = phead;         ListNode *pre = NULL;         while(cur != NULL){             ListNode *temp = cur->next;             cur->next = pre;             pre = cur;             cur = temp;         }         return pre;     }      ListNode* addInList(ListNode* head1, ListNode* head2) {         // write code here         if(head1 == NULL) return head2;         if(head2 == NULL) return head1;         head1 = reverselist(head1);         head2 = reverselist(head2);         ListNode *res = new ListNode(-1);         ListNode *head = res;         int carry = 0;         while(head1 != NULL || head2 != NULL || carry !=0){             int val1 = head1 == NULL ? 0:head1->val;             int val2 = head2 == NULL ? 0 : head2->val;             int temp = val1 + val2 + carry;             carry = temp/10;             temp %= 10;             head->next = new ListNode(temp);             head = head->next;             if(head1 != NULL){                 head1 = head1->next;             }             if(head2 != NULL){                 head2 = head2->next;             }         }         return reverselist(res->next);     } };采用辅助空间的方式public class Solution {     public ListNode addInList (ListNode head1, ListNode head2) {         // write code here         if(head1 == null)             return head2;         if(head2 == null){             return head1;         }         // 使用两个辅助栈,利用栈先进后出,相当于反转了链表         Stack stack1 = new Stack<>();         Stack stack2 = new Stack<>();         ListNode p1=head1;         ListNode p2=head2;         // 将两个链表的结点入栈         while(p1!=null){             stack1.push(p1);             p1=p1.next;         }         while(p2!=null){             stack2.push(p2);             p2=p2.next;         }         // 进位         int tmp = 0;         // 创建新的链表头节点         ListNode head = new ListNode(-1);         ListNode nHead = head.next;         while(!stack1.isEmpty()||!stack2.isEmpty()){             // val用来累加此时的数值(加数+加数+上一位的进位=当前总的数值)             int val = tmp;             // 栈1不为空的时候,弹出结点并累加值             if (!stack1.isEmpty()) {                 val += stack1.pop().val;             }             // 栈2不为空的时候,弹出结点并累加值             if (!stack2.isEmpty()) {                 val += stack2.pop().val;             }             // 求出进位             tmp = val/10;             // 进位后剩下的数值即为当前节点的数值             ListNode node = new ListNode(val%10);             // 将结点插在头部             node.next = nHead;             nHead = node;         }         if(tmp > 0){             // 头插             ListNode node = new ListNode(tmp);             node.next = nHead;             nHead = node;         }         return nHead;     } }
  单链表的排序数组形式:创建一个数组,将链表内容放入,然后排序完恢复链表形式class Solution { public:     ListNode* sortInList(ListNode* head) {         vector nums;          ListNode* p = head;         //遍历链表,将节点值加入数组         while(p != NULL){              nums.push_back(p->val);             p = p->next;         }         p = head;         //对数组元素排序         sort(nums.begin(), nums.end());          //遍历数组         for(int i = 0; i < nums.size(); i++){              //将数组元素依次加入链表             p->val = nums[i];              p = p->next;         }         return head;     } }; 递归形式:每次分成两部分,然后将分割后的部分进行局部排序,最终达到整体有序class Solution { public:     ListNode *mergelist(ListNode *phead1, ListNode *phead2){         if(phead1 == NULL) return phead2;         if(phead2 == NULL ) return phead1;         ListNode *head = new ListNode(0);         ListNode *cur = head;         while(phead1 && phead2){             if(phead1->val >phead2->val){                 cur->next = phead2;                 phead2 = phead2->next;             }else{                 cur->next = phead1;                 phead1 = phead1->next;             }             cur = cur->next;         }         if(phead1) cur->next = phead1;         else cur->next = phead2;         return head->next;     }     ListNode* sortInList(ListNode* head) {         // write code here         if(head == NULL || head->next == NULL) return  head;         ListNode *left = head;         ListNode *mid = head->next;         ListNode *right = head->next->next;         while(right != NULL && right->next != NULL){             left = left->next;             mid = mid->next;             right = right->next->next;         }         //左边指针指向左段的左右一个节点,从这里断开         left->next = NULL;          //分成两段排序,合并排好序的两段         return mergelist(sortInList(head), sortInList(mid));     } };
  判断链表是否为回文结构存入数组的方式,然后将数组反转后对比存入数组的方式,得到数组长度,双指针分别从两端开始class Solution { public:     bool isPail(ListNode* head) {         vector nums;         //将链表元素取出一次放入数组         while(head != NULL){              nums.push_back(head->val);             head = head->next;         }         //双指针指向首尾         int left = 0;          int right = nums.size() - 1;         //分别从首尾遍历,代表正序和逆序         while(left <= right){              //如果不一致就是不为回文             if(nums[left] != nums[right])                  return false;             left++;             right--;         }         return true;     } };快慢指针方式,记录到中间位置,然后反转后半部分,再对比(满足时间O(n),空间O(1))class Solution { public:     ListNode *reverse(ListNode *head){         ListNode *pre = NULL;         while(head != NULL){             ListNode *next = head->next;             head->next = pre;             pre = head;             head = next;         }         return pre;     }     bool isPail(ListNode* head) {         // write code here         ListNode *slow = head->next;         ListNode *fast = head;         while(fast->next != NULL && fast->next->next != NULL){             slow = slow->next;             fast = fast->next->next;         }         fast = head;         slow = reverse(slow);         while(slow != NULL){             if(fast->val != slow->val) return false;             slow = slow->next;             fast = fast->next;         }         return true;     } };
  链表的奇偶重排双指针的方式,将偶数的节点跳过,奇数的next直接指向下一个奇数,偶数则成为奇数的nextclass Solution { public:     ListNode* oddEvenList(ListNode* head) {         // write code here         if(head == NULL) return NULL;         ListNode *even = head->next;         ListNode *odd = head;         ListNode *evenodd = even;         while(even != NULL && even->next != NULL){             odd->next = even->next;             odd = odd->next;             even->next = odd->next;             even = even->next;         }         odd->next = evenodd;         return head;     } };
  删除有序链表中重复的所有元素从0开始,不从1开始,这样的话可以从重复节点的上一个开始判断,每一次遇到重复前都可以判断出后面两个是否有重复元素class Solution { public:     ListNode* deleteDuplicates(ListNode* head) {         // write code here        if(head == NULL) return NULL;        ListNode *res = new ListNode(0);        res->next = head;        ListNode *cur = res;        while(cur->next != NULL && cur->next->next != NULL) {            if(cur->next->val == cur->next->next->val){                int temp = cur->next->val;                while(cur->next != NULL && cur->next->val == temp){                    cur->next = cur->next->next;                }            }else cur = cur->next;          }        return res->next;     } };

天津女排终于放人了!姚迪前往意甲帮助朱婷,李盈莹被曝要价太高本赛季排超联赛已经全部结束,天津女排在三局两胜制的比赛中,两回合双杀上海女排拿到冠军,也是球队历史上第15座冠军奖杯,天津女排成为中国排坛历史上当之无愧的霸主。赛后公布的最佳阵容,仅打17场,年薪高达4200万,沃尔暗讽伦纳德,快船3。37亿打水漂本赛季快船队毫无疑问是最让人失望的一个赛季,因为他们的主力大将伦纳德至今还在休战当中,并且是打一场休10场,这样的样子,他的不稳定,出场在一定程度上打乱了快船队的化学反应,虽然现在必须承认,NBA现在顶薪泛滥,但是真配得上5000万年薪的就4人不得不承认,如今的NBA可以说是薪资泛滥,像奇才队的比尔,巅峰时期也就是刚达到全明星水准,利拉德,最高也就是全明星,还有唐斯,只能算数据刷子,然而这些人的薪资将来都会破5000万,13万停赛6场,西热力江路走窄了,向前同事口诛笔伐,霍楠扎心了提到西热力江,熟悉CBA的球迷往往会把他和真性情性格如火等一系列形容词联系到一起。球员时代的西热,因为在五棵松球馆对全场球迷做打伞动作,怒吼哈德森,对着韦弗竖中指,嘲讽老东家新疆队布莱克尼396吴冠希1614江苏险胜广州斩获3连胜北京时间1月9日,CBA联赛第二阶段比赛继续进行,江苏男篮对阵广州龙狮男篮。最终江苏10093战胜广州,取得了3连胜。双方数据广州祝铭震25分10篮板,贝尔13分8篮板4助攻2断4法国足协主席向齐达内道歉我愚蠢的言论造成了误解北京时间1月9日,据法国媒体RMC报道,当地时间周一,法国足协主席勒格拉埃在法新社上发布了一份声明,正式就此前的言论向齐达内表示了道歉。勒格拉埃表示,自己的言论很愚蠢,希望并向齐达9。9分的国漫神作,又被家长们冲了如果有人问,2023年国漫的开年神番是什么?那必须得是ThreeBody不对是中国奇谭呐!这个由上海电影美术制片厂(对没错就是它)和B站联合出品的原创网络动画短片合集,总共8集,均太意外!辽自媒体造谣抹黑曾繁日,无底线令人发指,支持严惩不贷最近,广东队球员曾繁日成为了某地球迷讨论的热议话题,甚至,打着辽宁飞豹球迷联盟的自媒体账号,竟然造谣抹黑曾繁日,简直就是毫无底线,这样的行径确实让人感到深恶痛绝。下面,就跟大家具体脖子上挂大饼的第一懒人天下第一懒人杨锁当他还是个孩子的时候,他想帮助他的父母工作,但因为他的父母溺爱他,没有让他做。如果他的父母选择让他帮忙做一些农活,让他自力更生,帮助家人分担一些家务,也许他不会弄成魏晋第一美男嵇康竹林七贤之首39岁冤死,以千古绝响广陵散别世公元263年的这天,堪称中国文化史上最为黑暗的一天,位于洛阳东市的刑场上,人山人海挤满了人,今天要被行刑的人是大名鼎鼎的魏晋当代名士嵇康。这天洛阳城堪称万人空巷,尤其洛阳东市的刑场塞舌尔5万晚,我住进了威廉王子凯特王妃度蜜月的私密岛酒店!塞舌尔的独立小岛Northlsland,极其出名。这个只有11栋别墅每晚最低要5万人民币的度假酒店,把世界上众多知名酒店品牌,包括迪拜卓美亚帆船酒店和马尔代夫的岛王路易威登旗下的白
又有4款2年前机型可以升级HarmonyOS3,花粉总算等到了!不得不说,华为对系统的适配速度还是非常快的,从9月份发布HarmonyOS3以来,已经对几十款手机进行了适配升级,基本上这两年发布的新款华为手机都已经可以尝鲜HarmonyOS3了竟比国外贵了一倍?宝马XM国内售价曝光,起步价230万!我们知道在新能源汽车的大环境下,越来越多的汽车品牌开始逐渐转型,包括BBA!而在最近,宝马旗下的全新概念的混动SUVXM的国内价格也正式曝光,价格已出,国内的小伙伴彻底不淡定了,同评论之星漫评千亿快件彰显我国经济无限潜力杨卓艺黄钰彤(山东大学)近日,受疫情影响,多地快递员人力不足,导致快递件滞留。通过网络上盛传现场图片看出,这些快递数量庞大,商品种类繁多。可见,尽管面对经济下行压力,我国民众的消费一加喊出可以不要硬件利润,多方角力下线上蛋糕怎么分?在重新并入OPPO后,一加近日获得百亿元投资,重整资源攻入线上渠道。未来三年我们希望在两千元档位的线上市场中做到份额第一。一加中国区总裁李杰近日对包括第一财经在内的记者表示,未来三15。餐厅选址数据测算投资可行性分析选址时,判断一个位置是否适合开餐厅,需要一个投资可行性分析模型。通过这个模型我们可以计算得到三个数据餐厅需求人流量,餐厅需求面积,每平方米的日租金。与我们实际测量人流量的数据实际餐重磅!东莞签下580亿大单,这些镇街将迎大发展12月21日,2022粤港澳大湾区全球招商大会在广州召开。东莞共有签约项目31宗,涉及投资金额581。43亿元。其中,有3宗项目在台上集中签约,分别为麻涌赣锋锂电项目寮步高伟光学项苏州房价,坠落了!作者子非鱼01苏州楼市全线调整没有人怀疑中国最牛地级市苏州的城市价值与潜力,就像没有人怀疑深圳一样。但当房价水平远远超出城市价值和潜力所能匹配的高度,远远超出城市大多数居民本身的购赣锋锂业孚能科技回应碳酸锂降价拐点未至(文张家栋编辑马媛媛)据多家检测机构数据显示,近日国内电池级碳酸锂价格正连续经历大幅回落,至12月21日,国内电池级碳酸锂价格已经下降至55万元吨,短短一周时间内便下降近2万元吨,项目投融资公司注册,公司注销代理公司商标注册代理香港日聪企业一站式服务公司项目投融资是项目融资的一种方式,是指投资方通过一定的渠道和方式对项目进行投资的过程。1定义投资项目投融资(Proje证监会大力支持房地产市场平稳发展证监会表示,大力支持房地产市场平稳发展。加大力度加快速度抓好资本市场各项支持政策措施落地见效,助力房地产发展模式转型。全面落实改善优质房企资产负债表计划,继续实施民企债券融资专项支造手机的三星还生产过卡车?曾与曼恩合作,带您回顾三星卡车历史说起三星这个品牌,您一定有所了解。作为一家全球知名的韩国企业,三星的业务可谓是相当的广泛。从手机平板相机,再到屏幕闪存颗粒等电子元器件,三星都有生产。除了在电子领域叱咤风云之外,三