【群视频】笔记 - 2015.06.03
2015-06-21 03:10
274 查看
[code]贪心策略 ——刷题初期 先不要搞。
拼接所有字符串产生字典顺序最小的大字符串
例如字符串数组{c,a,b},按照a、b、c的顺序拼接后的大字符串为abc,是字典顺序最小的。
[code]package test; import java.util.Arrays; import java.util.Comparator; class MergeComparator implements Comparator<String> { @Override public int compare(String arg0, String arg1) { return (arg0 + arg1).compareTo(arg1 + arg0); } public class MergeStringsLowestLexicography { public static String lowestString(String[] strs) { Arrays.sort(strs, new MergeComparator()); String res = ""; for (int i = 0; i != strs.length; i++) { res += strs[i]; } return res; } public static void main(String[] args) { String[] strArr = { "jibw", "ji", "jp", "bw", "jibw" }; String result = lowestString(strArr); System.out.println(result); } }
从5随机到7随机及其扩展
【题目】 给定一个等概率随机产生1~5的随机函数rand1To5如下: public int rand1To5()
{
return (int) (Math.random() * 5) + 1; } 除此之外不能使用任何额外的随机机制,请用rand1To5实现等概率随机产生1~7的随机函数rand1To7。 【补充题目】
给定一个以p概率产生0,以1-p概率产生1的随机函数rand01p如下: public int rand01p() {
// you can change p as you like
double p = 0.83;
return Math.random() < p ? 0 : 1; } 除此之外不能使用任何额外的随机机制,请用rand01p实现等概率随机产生1~6的随机函数rand1To6。 【进阶题目】
给定一个等概率随机产生1~M的随机函数rand1ToM如下: public int rand1ToM(int m) {
return (int) (Math.random() * m) + 1; } 除此之外不能使用任何额外的随机机制。有两个输入参数分别为m和n,请用rand1ToM(m)实现等概率随机产生1~n的随机函数rand1ToN。
【题目】
[code]public int rand1To5() { return (int) (Math.random() * 5) + 1; } public int rand1To7() { int num = 0; do { num = (rand1To5() - 1) * 5 + rand1To5() - 1; } while (num > 20); return num % 7 + 1; }
【补充题目】
[code]public int rand01() { int num; do { num = rand01p(); } while (num == rand01p()); return num == 1 ? 1 : 0; }
【进阶题目】
已知1~M的随机,请实现1~N的随机。
[code]public int rand1ToM(int m) { return (int) (Math.random() * m) + 1; } public int rand1ToN(int n, int m) { int[] nMSys = getMSysNum(n - 1, m); int[] randNum = getRanMSysNumLessN(nMSys, m); return getNumFromMSysNum(randNum, m) + 1; } // 把value转成m进制的数 public int[] getMSysNum(int value, int m) { int[] res = new int[32]; int index = res.length - 1; while (value != 0) { res[index--] = value % m; value = value / m; } return res; } // 等概率随机产生一个0~nMsys范围上的数,只不过是m进制表达的。 public int[] getRanMSysNumLessN(int[] nMSys, int m) { int[] res = new int[nMSys.length]; int start = 0; while (nMSys[start] == 0) { start++; } int index = start; boolean lastEqual = true; while (index != nMSys.length) { res[index] = rand1ToM(m) - 1; if (lastEqual) { if (res[index] > nMSys[index]) { index = start; lastEqual = true; continue; } else { lastEqual = res[index] == nMSys[index]; } } index++; } return res; } // 把m进制的数转成10进制 public int getNumFromMSysNum(int[] mSysNum, int m) { int res = 0; for (int i = 0; i != mSysNum.length; i++) { res = res * m + mSysNum[i]; } return res; }
【题目】 给定一个无序数组arr,求出需要排序的最短子数组长度。 例如: arr = [1,5,3,4,2,6,7]
返回4,因为只有[5,3,4,2]需要排序。
【解】:
时间复杂度: O(n)
额外空间复杂度: O(1)
先左→右,找出max
再右→左,找min
因为求的是需要排序的最短子数组长度。
[code]public int getMinLength(int[] arr) { if (arr == null || arr.length < 2) { return 0; } int min = arr[arr.length - 1]; int noMinIndex = -1; for (int i = arr.length - 2; i != -1; i--) { if (arr[i] > min) { noMinIndex = i; } else { min = Math.min(min, arr[i]); } } if (noMinIndex == -1) { return 0; } int max = arr[0]; int noMaxIndex = -1; for (int i = 1; i != arr.length; i++) { if (arr[i] < max) { noMaxIndex = i; } else { max = Math.max(max, arr[i]); } } return noMaxIndex - noMinIndex + 1; }
最大的leftMax与rightMax之差的绝对值 【题目】
给定一个长度为N(N>1)的整型数组arr,可以划分成左右两个部分,左部分arr[0..K],右部分arr[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?
例如[2,7,3,1,1],当左部分为[2,7],右部分为[3,1,1]时,左部分中的最大值减去右部分最大值的绝对值为4。当左部分为[2,7,3],右部分为[1,1]时,左部分中的最大值减去右部分最大值的绝对值为6。还有很多划分方案,但最终返回6。
【解】:
时间复杂度: O(n)
额外空间复杂度: O(1)
[code]public int maxABS3(int[] arr) { int max = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) { max = Math.max(arr[i], max); } return max - Math.min(arr[0], arr[arr.length - 1]); }
[code][方法一]:(不得分) public int maxABS1(int[] arr) { int res = Integer.MIN_VALUE; int maxLeft = 0; int maxRight = 0; for (int i = 0; i != arr.length - 1; i++) { maxLeft = Integer.MIN_VALUE; for (int j = 0; j != i + 1; j++) { maxLeft = Math.max(arr[j], maxLeft); } maxRight = Integer.MIN_VALUE; for (int j = i + 1; j != arr.length; j++) { maxRight = Math.max(arr[j], maxRight); } res = Math.max(Math.abs(maxLeft - maxRight), res); } return res; }
[code][方法二]:(空间换时间) public int maxABS2(int[] arr) { int[] lArr = new int[arr.length]; int[] rArr = new int[arr.length]; lArr[0] = arr[0]; rArr[arr.length - 1] = arr[arr.length - 1]; for (int i = 1; i < arr.length; i++) { lArr[i] = Math.max(lArr[i - 1], arr[i]); } for (int i = arr.length - 2; i > -1; i--) { rArr[i] = Math.max(rArr[i + 1], arr[i]); } int max = 0; for (int i = 0; i < arr.length - 1; i++) { max = Math.max(max, Math.abs(lArr[i] - rArr[i + 1])); } return max; }
现在有一种新的二叉树节点类型如下:
[code]public class Node { public int value; public Node left; public Node right; public Node parent; public Node(int data) { this.value = data; } }
该结构比普通二叉树节点结构多了一条指向父节点的parent指针。假设有一棵Node类型的节点组成的二叉树,树中每个节点的parent指针都正确的指向自己的父节点,头节点的parent指向null。只给一个在二叉树中的某个节点node,请实现返回node的后继节点的函数。在二叉树的中序遍历的序列中,node的下一个节点叫做node的后继节点。
【解】:
[code]public Node getNextNode(Node node) { if (node == null) { return node; } if (node.right != null) { return getLeftMost(node.right); } else { Node parent = node.parent; while (parent != null && parent.left != node) { node = parent; parent = node.parent; } return parent; } } public Node getLeftMost(Node node) { if (node == null) { return node; } while (node.left != null) { node = node.left; } return node; }
相关文章推荐
- win7安装Infragistics NetAdvantage,报错
- leetcode-217-Contains Duplicate
- C++ stderr/stdout 重定向到文件
- ubuntu 安装 google Gtest
- BOZJ2733 [HNOI2012]永无乡(Treap+启发式合并)
- 委托
- 永远要回避模糊的事务和技术的难度
- 永远要回避模糊的事务和技术的难度
- HTTPS 客户端发送请求(二)
- CUDA ---- CUDA库简介
- Ruby Variable Scope 简单讲解
- JAVA 常用数据结构操作
- mock.js-无需等待,让前端独立于后端进行开发
- cocos 背景无限滑动!
- 罗素悖论的始末以及对现代数学走向的影响
- 05_学生管理系统,xml读写,布局的综合应用
- 05_学生管理系统,xml读写,布局的综合应用
- HTTPS 客户端发送请求(一)
- Web性能优化:What? Why? How?
- 换主页轮播的主题图片(2、添加)---轻开电子商务系统(企业入门级B2C网站)