赞
踩
最近一直在刷算法,以前没有重视这块,偶然巧合下,想到了某几次的面试,虽然没有以这个为主,但是也都有问过算法的题,因为没有这方面的积累,所以心底里一直抗拒,最近也有时间,觉得还是要花时间学习研究算法的东西,锻炼锻炼逻辑思路和解决思路。
学习路程肯定是要把基础掌握好的,你得知道各个名词的含义,如链表是什么,单链表怎么实现,双链表怎么实现,你才能处理把握链表出的方向的算法题,如树,什么是二叉树,二叉搜索树,二三树,红黑树,你知道每个结构的定义以及特性,才能掌握和思考怎么处理,这一定是必然的。
今天弄几个链表算法
1.对单链表逆顺序是否与原链表顺序相同,也就是回文链表,如1->2 ->1,那么1->2->1这个就是true,如1->2,那么逆序就是2->1那么就是false;
因为链表有个特点不知道长度,不能随机用下标访问数据,所以需要遍历到最后才能全部知道数据,这道题可以采用先遍历将链表数据存储到数组中,然后采用二分法进行前后对比数据,直到遇到不相等则直接退出循环,返回false,一直相等则就是链表的回文数据,
- public boolean isPail (ListNode head) {
- List<Integer> list = new ArrayList();
- ListNode w = head;
- // 将链表数据存储到数组中
- while (w != null) {
- list.add(w.val);
- w = w.next;
- }
-
- int size = list.size();
- boolean result = true;
- // 将数组长度/2 得到回文顺序交界点
- for (int i = 0; i < size / 2; i++) {
- // 从前往后对比直到交界点,全部都比对完毕
- if (list.get(i).equals(list.get(size - i - 1))) {
- } else {
- result = false;
- break;
- }
- }
- return result;
- }
-
- // 节点,是个内部类
- public static class ListNode {
- int val;
- ListNode next = null;
- }
测试示例
- ListNode ListNode = new ListNode();
- ListNode.val = 1;
- ListNode.next = null;
-
- ListNode ListNodeNext = new ListNode();
- ListNodeNext.val = 2;
- ListNodeNext.next = null;
- ListNode.next = ListNodeNext;
-
-
- ListNode ListNodeNextn = new ListNode();
- ListNodeNextn.val = 3;
- ListNodeNextn.next = null;
- ListNodeNext.next = ListNodeNextn;
-
- ListNode ListNodeNextns = new ListNode();
- ListNodeNextns.val = 3;
- ListNodeNextns.next = null;
- ListNodeNextn.next = ListNodeNextns;
-
- ListNode ListNodeNextnn = new ListNode();
- ListNodeNextnn.val = 2;
- ListNodeNextnn.next = null;
- ListNodeNextns.next = ListNodeNextnn;
-
- ListNode ListNodeNextnns = new ListNode();
- ListNodeNextnns.val = 1;
- ListNodeNextnns.next = null;
- ListNodeNextnn.next = ListNodeNextnns;
- System.out.println(AboutLinked.isPail2(ListNode));
输入:1->2->3->3-2>1返回结果 true
自己写的一个版本,当时主要考虑不想遍历放入数组中,再次进行遍历,所以用了String的字符串拼接方式。
- public boolean isPail (ListNode head) {
- String s="";
- String ss ="";
- ListNode w = head;
- while (w != null) {
- s+=w.val+"";
- ss=w.val+ss;;
- w = w.next;
- }
- return s.equals(ss);
- }
这种方式答案是对的,但是性能太差,输入量特多的情况下,会超时反馈不出结果,我想主要原因还是出在了字符串拼接导致的问题,我本想减少代码,减少一些遍历,但是却出现了其他的性能问题,不用StringBuffer的原因是想要倒着拼接,如果使用reverse则负数又会出现问题,
String采用连接运算符(+)效率低下,都是上述循环、大批量数据情况造成的,每做一次"+"就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后append字符串,如此循环直至结束。如果我们直接采用StringBuilder对象进行append的话,我们可以节省创建和销毁对象的时间。
输入两个非公共的链表{1,2,3}以及{4,5}和一个公共链表{6,7},塞入到两个公共链表里头,变为{1,2,3,6,7}以及{4,5,6,7},请输出他们的第一个公共节点,那么得到的就是{6,7}
我们需要两个链表一一比对,直到某个链表为空,另一个链表还有值时进行两个链表替换,然后继续对比,本示例当对比空以后将temp赋值为temp2{1,2,3,6,7},temp2赋值为temp则{4,5,6,7},当temp链表走到空时,temp2链表已经赋值为1,那么当temp为空时,就赋值temp2为4,此时temp就为2,就变成了2:4,3:5,6:6 相同直接结束循环,是不是清楚很多,那么代码如下
- public class Solution {
- public static class ListNode {
- int val;
- ListNode next = null;
- }
- // pHead1={1,2,3,6,7} pHead2={4,5,6,7}
- public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
- ListNode temp = pHead1;
- ListNode temp1 = pHead2;
-
- while (temp != temp1) {
- // 如果为空互相替换来找出公共节点
- temp = temp!=null?temp.next:pHead2;
- temp1 = temp1!=null?temp1.next:pHead1;
- }
- return temp;
- }
-
- }
咱们就不演示测试了否择还得遍历打印链表,本次案例结果返回6->7
这个就是得到链表中倒数第几个结点,如 {1,2,3,4,5},然后传入2,则得到{4,5},传入3则得到链表倒数第三个以及之后的节点数据,如果链表的长度不足倒数得结点,则返回空节点
原链表为{1,2,3,4,5} 我需要让快指针走,走的终点是k,走到了k的值以后,再快慢链表一起走,最后返回慢指针就是想要的最后k个结点。
先循环,循环从0开始到k结束,那么第一个循环,快链表指针(fast)={2,3,4,5}
循环到1,fast={3,4,5},假如传的是2,那么循环到此则结束循环
快指针已得到,进行while循环,终止条件是快指针为空,fast={4,5} slow={2,3,4,5}
fast={5},slow={3,4,5}
fast={},slow={4,5} 结束循环,得到{4,5}
这里可采用快慢指针的思想,这样代码实现就很简单,
- public ListNode FindKthToTail (ListNode pHead, int k) {
- ListNode fast = pHead;
- // 快的指针先走,按k的步长走,如果为空则链表代表不足k个节点,返回空
- for (int i = 0; i < k; i++) {
- if (fast == null)
- return null;
- fast = fast.next;
- }
- // 快指针提前走了指定步长,直到快指针为空,则我们需要的就是慢指针的节点
- ListNode slow = pHead;
- while(fast!=null){
- fast=fast.next;
- slow=slow.next;
- }
- return slow;
- }
我自己有写过一个,思想和这个差不多,但是写完还是比这个复杂了,我采取的是,循环达到k点,就记录一个节点,直到找到空,就把存储的节点的下一个拿到,也就是将{1,2,3,4,5} 循环到3的时候将fast={3,4,5},循环到4的时候判断达不到到k个节点就为空了,如果是,则直接返回,不是就继续last={4,5},这种方式太冗余了,还要进行空啊或者其他不足k的判断,所以我们还是学会和使用简洁方式
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。