1 比较重量
小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量。这些钻石的重量各不相同。在他们们比较了一段时间后,它们看中了两颗钻石g1和g2。现在请你根据之前比较的信息判断这两颗钻石的哪颗更重。 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号。最后给定之前的比较次数n。请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合法,不会有矛盾情况出现。 测试样例: 2,3,[[1,2],[2,4],[1,3],[4,3]],4 返回: 1
思路:有向图,生成图的邻接矩阵后通过prim算法判断两点之间是否有路径。
1 import java.util.*; 2 3 public class Cmp { 4 public int cmp(int g1, int g2, int[][] records, int n) { 5 // write code here 6 int maxNum = -1; 7 for (int i = 0; i < n; i++){ 8 maxNum = maxNum > records[i][0] ? maxNum : records[i][0]; 9 maxNum = maxNum > records[i][1] ? maxNum : records[i][1]; 10 } 11 boolean [][] dis = new boolean [maxNum + 1][maxNum + 1]; 12 for (int i = 1; i <= maxNum; i++){ 13 dis[i][i] = true; 14 } 15 for (int i = 0; i < n; i++){ 16 dis[records[i][0]][records[i][1]] = true; 17 } 18 for (int k = 1; k <= maxNum; k++){ 19 for (int i = 0; i <= maxNum; i++){ 20 for (int j =0; j <= maxNum; j++){ 21 if (dis[i][k] && dis[k][j]){ 22 dis[i][j] = true; 23 } 24 } 25 } 26 } 27 if (dis[g1][g2]){ 28 return 1; 29 } else if (dis[g2][g1]){ 30 return -1; 31 } else { 32 return 0; 33 } 34 } 35 }
错误思路 :直接递归找,有环是死循环。
1 import java.util.*; 2 3 public class Cmp { 4 public int cmp(int g1, int g2, int[][] records, int n) { 5 // write code here 6 7 for (int i = 0; i < n; i++){ 8 if(records[i][0] == g1){ 9 if(records[i][1] == g2){ 10 return 1; 11 } 12 if (cmp(records[i][1], g2, records, n) == 1){ 13 return 1; 14 } 15 } 16 } 17 for (int i = 0; i < n; i++){ 18 if(records[i][0] == g2){ 19 if(records[i][1] == g1){ 20 return 1; 21 } 22 if (cmp(records[i][1], g1, records, n) == 1){ 23 return 1; 24 } 25 } 26 } 27 return 0; 28 } 29 public static void main(String [] args){ 30 int [][] a = {{1,2},{2,4},{1,3},{4,3}}; 31 System.out.println(new Cmp().cmp(2, 3, a, 4)); 32 } 33 }
2 二叉树
1 有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。 2 给定二叉树的根节点root,请返回所求距离。
思路:二进制编码,然后在编码上找最近公共祖先之后的长度和。
1 import java.util.*; 2 3 /* 4 public class TreeNode { 5 int val = 0; 6 TreeNode left = null; 7 TreeNode right = null; 8 public TreeNode(int val) { 9 this.val = val; 10 } 11 }*/ 12 public class Tree { 13 private int min = Integer.MAX_VALUE; 14 private int max = Integer.MIN_VALUE; 15 private String minCode; 16 private String maxCode; 17 public int getDis(TreeNode root) { 18 // write code here 19 binaryCode(root.left, "0", ""); 20 binaryCode(root.right, "1", ""); 21 int minLen = minCode.length(); 22 int maxLen = maxCode.length(); 23 int i = 0; 24 while (i < minLen && i < maxLen && minCode.charAt(i) == maxCode.charAt(i)){ 25 i++; 26 } 27 return minLen + maxLen - 2 * i; 28 } 29 private void binaryCode(TreeNode node, String code, String prev){ 30 if (node == null){ 31 return; 32 } 33 String curCode = prev + code; 34 if (node.left == null && node.right == null){ 35 if (node.val < min){ 36 min = node.val; 37 minCode = curCode; 38 } 39 if (node.val > max){ 40 max = node.val; 41 maxCode = curCode; 42 } 43 return; 44 } 45 binaryCode(node.left, "0", curCode); 46 binaryCode(node.right, "1", curCode); 47 } 48 }
3 寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。 测试样例: [1,3,5,2,2],5,3 返回:2
思路1: 快排,然后判断要的数是在左边还是右边再递归对该部分排序, 注意优化,不用每次都移动。
1 public class Finder { 2 public int findKth(int[] a, int n, int K) { 3 return findKth(a, 0, n-1, K); 4 } 5 6 public int findKth(int[] a, int low, int high, int k) { 7 int part = partation(a, low, high); 8 9 if(k == part - low + 1) return a[part]; 10 else if(k > part - low + 1) return findKth(a, part + 1, high, k - part + low -1); 11 else return findKth(a, low, part -1, k); 12 13 } 14 15 public int partation(int[] a, int low, int high) { 16 int key = a[low]; 17 18 while(low < high) { 19 while(low < high && a[high] <= key) high--; 20 a[low] = a[high]; 21 while(low < high && a[low] >= key) low++; 22 a[high] = a[low]; 23 } 24 a[low] = key; 25 return low; 26 } 27 }
思路2:二叉堆维护最大的K个数(最小堆)。
1 import java.util.*; 2 3 public class Finder { 4 public int findKth(int[] a, int n, int K) { 5 // write code here 6 Queue<Integer> priorityQueue = new PriorityQueue<Integer>(); 7 for (int i = 0; i < n; i++){ 8 if (i < K){ 9 priorityQueue.add(a[i]); 10 } else if (priorityQueue.peek() < a[i]){ 11 priorityQueue.remove(); 12 priorityQueue.add(a[i]); 13 } 14 } 15 return priorityQueue.remove(); 16 } 17 }
快排更优。
时间: 2024-10-10 14:56:21