【剑指offer】11-20题
来源:互联网 发布:犹大福音 知乎 编辑:程序博客网 时间:2024/06/10 19:28
11.给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不得使用库函数,不需要考虑大数问题
思路:不能用==比较两个浮点数是否相等,因为有误差。考虑输入值的多种情况。
代码实现:
public double Power(double base, int exponent) { double res = 0; if (equal(base,0)) { return 0; } if (exponent == 0) { return 1.0; } if (exponent > 0) { res = mutiply(base,exponent); }else { res = mutiply(1/base,-exponent); } return res;}public double mutiply(double base, int e) { double sum = 1; for (int i = 0; i < e; i++) { sum = sum * base; } return sum;}public boolean equal(double a, double b) { if (a - b < 0.000001 && a - b > -0.000001) { return true; } return false;}
12.打印1到最大的n位数
思路:考虑大数问题,使用字符串或数组表示。
代码实现:
public void printToMaxOfNDigits(int n) { int[] array=new int[n]; if(n <= 0) return; printArray(array, 0);}private void printArray(int[] array,int n) { for(int i = 0; i < 10; i++) { if(n != array.length) { array[n] = i; printArray(array, n+1); } else { boolean isFirstNo0 = false; for(int j = 0; j < array.length; j++) { if(array[j] != 0) { System.out.print(array[j]); if(!isFirstNo0) isFirstNo0 = true; } else { if(isFirstNo0) System.out.print(array[j]); } } System.out.println(); return ; } }}
13.O(1)时间删除链表节点
思路:将要删除节点的下一个节点的值赋给要删除的节点,然后指向下下一个节点
代码实现:
public void deleteNode(ListNode head, ListNode deListNode) { if (deListNode == null || head == null) return; if (head == deListNode) { head = null; } else { // 若删除节点是末尾节点,往后移一个 if (deListNode.nextNode == null) { ListNode pointListNode = head; while (pointListNode.nextNode.nextNode != null) { pointListNode = pointListNode.nextNode; } pointListNode.nextNode = null; } else { deListNode.data = deListNode.nextNode.data; deListNode.nextNode = deListNode.nextNode.nextNode; } }}
14.输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
思路:每次只和前面一个数交换位置。或者利用辅助数组
代码实现:
public void reOrderArray(int [] array) { if(array == null) return ; for(int i = 1; i < array.length; i++){ int temp = array[i]; int j = i - 1; if(array[i] % 2 != 0){ while(j >= 0){ if(array[j] % 2 != 0){ break; } if(array[j]%2 == 0){ int t = array[j+1]; array[j+1] = array[j]; array[j] = t; j--; } } } array[j+1] = temp; }}
15.输入一个链表,输出该链表中倒数第k个结点。
扩展题:找中间节点,使用两个指针,一个走一步,一个走两步。找到中间节点
思路:定义一快一慢两个指针,快指针走K步,然后慢指针开始走,快指针到尾时,慢指针就找到了倒数第K个节点。
代码实现:
public ListNode FindKthToTail(ListNode head,int k) { if (head == null || k <= 0) { return null; } ListNode fast = head; ListNode slow = head; while(k-- > 1) { if (fast.next != null) fast = fast.next; else return null; } while (fast.next != null) { fast = fast.next; slow = slow.next; } return slow;}
16.输入一个链表,反转链表后,输出链表的所有元素。
扩展题:输出反转后链表的头节点,定义三个指针反向输出。
思路:定义两个指针,反向输出
代码实现:
public ListNode ReverseList(ListNode head) { if (head == null) { return null; } ListNode temp = null; while(head != null) { ListNode p = head.next; head.next = temp; temp = head; head = p; } return temp;}
17.输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:递归与非递归求解,小数放在前面。
代码实现:
public ListNode Merge(ListNode list1,ListNode list2) { if (list1 == null) { return list2; } if (list2 == null) { return list1; } ListNode newHead = null; if (list1.val <= list2.val) { newHead = list1; newHead.next = Merge(list1.next,list2); }else { newHead = list2; newHead.next = Merge(list1,list2.next); } return newHead;}
18.输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:若根节点相等,利用递归比较他们的子树是否相等,若根节点不相等,则利用递归分别在左右子树中查找。
代码实现:
public boolean HasSubtree(TreeNode root1,TreeNode root2) { boolean result = false; if (root2 != null && root1 != null) { if(root1.val == root2.val){ result = doesTree1HaveTree2(root1,root2); } if (!result) return HasSubtree(root1.left,root2) || HasSubtree(root1.right,root2); } return result;}public boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2) { if (node2 == null) { return true; } if (node1 == null) { return false; } if (node1.val != node2.val) { return false; } return doesTree1HaveTree2(node1.left,node2.left) && doesTree1HaveTree2(node1.right,node2.right);}
19.操作给定的二叉树,将其变换为源二叉树的镜像。
思路:使用递归或非递归方式交换每个节点的左右子树位置。
代码实现:
public void Mirror(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<>(); while (root != null || !stack.isEmpty()) { while (root != null) { TreeNode temp = root.left; root.left = root.right; root.right = temp; stack.push(root); root = root.left; } if (!stack.isEmpty()) { root = stack.pop(); root = root.right; } }}
20.输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
思路:终止行号大于起始行号,终止列号大于起始列号,
代码实现:
public ArrayList<Integer> printMatrix(int[][] matrix) { ArrayList<Integer> list = new ArrayList<>(); if(matrix == null) return list; int start = 0; while(matrix[0].length > start*2 && matrix.length > start*2) { printOneCircle(matrix,start,list); start++; } return list;}private void printOneCircle(int[][] matrix,int start,ArrayList<Integer> list) { int endX = matrix[0].length - 1 - start; // 列 int endY = matrix.length - 1 - start; // 行 // 从左往右 for (int i = start; i <= endX; i++) list.add(matrix[start][i]); // 从上往下 if (start < endY) { for (int i = start + 1; i <= endY; i++) list.add(matrix[i][endX]); } // 从右往左(判断是否会重复打印) if (start < endX && start < endY) { for (int i = endX - 1; i >= start; i--) list.add(matrix[endY][i]); } // 从下往上(判断是否会重复打印) if (start < endX && start < endY - 1) { for (int i = endY - 1; i >= start + 1; i--) list.add(matrix[i][start]); }}
未完待续。。。。。
- 【剑指offer】11-20题
- 剑指offer题20
- 剑指offer题11
- 剑指offer(11-20)
- 剑指offer 试题11~20
- 【剑指Offer】鸟瞰50题之11 - 20题
- 【刷题笔记/剑指Offer】Part 2 (11-20)
- 【剑指offer】题20:顺时针打印矩阵
- 剑指offer-20
- 【16-20】剑指offer
- 剑指Offer-20
- 【11-15】剑指offer
- 剑指Offer-11
- 剑指offer第一题
- 剑指offer-题
- 剑指offer第一题
- 剑指Offer第一题
- 剑指offer(题三)
- Gaclib 小白使用教程(1)
- 前端基础学习(一)10.30--11.1
- C++ explict关键词详解
- 《智能时代》读书笔记
- SolrCloud 集群详解
- 【剑指offer】11-20题
- 小浮动
- 与IP地址相关的几个结构体
- Spring之IOC
- cqbzoj3474 信仰(hineven模拟赛t3,Hash出奇迹)
- 【剑指offer】21-30题
- Oracle数据库 Select语句 day02
- Freemarker模板引擎技术
- TensorFlow官方文档中文版-笔记(四)