【面试必备】手撕代码,你怕不怕? (7)

题目描述:找出两个链表的第一个公共结点;

/** * 求两个链表中第一个公共结点 * * @param pHead1 链表1头结点 * @param pHead2 链表2头结点 * @return 链表第一个公共结点 */ public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { // 1.正确性判断 if (null == pHead1 || null == pHead2) { return null; } // 2.遍历链表1把所有结点保存在列表中中 Vector<ListNode> nodeList1 = new Vector<>(); while (null != pHead1) { nodeList1.add(pHead1); pHead1 = pHead1.next; // 判断是否成环,成环则退出循环 if (nodeList1.contains(pHead1)) { break; } } // end while:链表1中的所有结点都存入了nodeList1中 // 3.遍历链表2比较列表中的数据 Vector<ListNode> nodeList2 = new Vector<>(); while (null != pHead2) { // 先判断nodeList1中是否存在相同结点,存在则返回 if (nodeList1.contains(pHead2)) { return pHead2; } // 如果不存在则继续遍历,并判断是否成环 nodeList2.add(pHead2); pHead2 = pHead2.next; if (nodeList2.contains(pHead2)) { break; } } // end while:遍历完了链表2并将所有结点保存在了nodeList2中 // 如果遍历完链表2则返回null return null; }

需要注意的细节是:①正确性判断;②判断链表是否自己成环;③注释;④注意要自己写测试用例啊...

另外还有一些类似的题目像是:①链表入环结点;②链表倒数第k个结点;之类的都是需要掌握的...

4.二分查找算法

二分查找也是一类比较常考的题目,其实代码也比较容易理解,直接上吧,再再再提醒一下:注意正确性判断还有测试用例...

普通实现 /** * 二分查找普通实现。 * * @param srcArray 有序数组 * @param key 查找元素 * @return 不存在返回-1 */ public static int binSearch(int srcArray[], int key) { int mid; int start = 0; int end = srcArray.length - 1; while (start <= end) { mid = (end - start) / 2 + start; if (key < srcArray[mid]) { end = mid - 1; } else if (key > srcArray[mid]) { start = mid + 1; } else { return mid; } } return -1; } 递归实现 /** * 二分查找递归实现。 * * @param srcArray 有序数组 * @param start 数组低地址下标 * @param end 数组高地址下标 * @param key 查找元素 * @return 查找元素不存在返回-1 */ public static int binSearch(int srcArray[], int start, int end, int key) { int mid = (end - start) / 2 + start; if (srcArray[mid] == key) { return mid; } if (start >= end) { return -1; } else if (key > srcArray[mid]) { return binSearch(srcArray, mid + 1, end, key); } else if (key < srcArray[mid]) { return binSearch(srcArray, start, mid - 1, key); } return -1; } 5.斐波那契数列

这也是一道很经典的题,通常是要要求 N 值的范围的,常规写法应该很简单,所以需要掌握的是优化之后的算法:

public int Fibonacci(int n) { // 正确性判断 if (0 == n || 1 == n) { return n; } int nums1 = 0, nums2 = 1; int res = 0; for (int i = 2; i <= n; i++) { res = nums1 + nums2; nums1 = nums2; nums2 = res; } return res; }

还是注意正确性判断然后写测试用例...

手撕代码总结

如果用手写代码的话,确实是个挺麻烦的事儿,首先需要对代码有相当的熟悉程度,然后其次的话考察的都是一些细节的东西,例如:

编码规范:包括一些命名的规范/ 注释的规范等等;

缩进:这个我自己倒是挺在意的..关于这个可以去参考参考阿里出的那个规范手册;

注释:如果命名规范做得好的话其实是可以达到代码即注释的,但是仍然有一些需要标注的地方例如函数头之类的,最好还是做好注释;

代码的完整性:我觉得这个包括对于错误的处理/ 正确性判断这样一类的东西;

测试用例:每个函数都需要一定的测试来保证其正确性,所以这个还是挺有必要的,特别是一些边界情况,null 值判断之类的;

想好再下笔:这一点其实也蛮重要的,不管是在纸上还是在我们平时的编程中,思路永远都是更重要的;

说来说去还是关于代码的事,我觉得还是理清思路最重要,所以我们需要在一遍一遍熟悉代码的过程中,熟知这些代码的思路,只有搞清楚这些代码背后的原理了,我们才能正确且快速的写出我们心中想要的代码,而不是简单的去背诵,这样是没有很大效果的,以上...

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdpfy.html