1、有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
1 using System; 2 using System.Linq; 3 using System.Collections.Generic; 4 namespace ConsoleApplication1 5 { 6 class Program 7 { 8 static Random Rand = new Random(); 9 10 static void Main(string[] args) 11 { 12 int count = 10000; 13 List<int> Input = new List<int>(); 14 // for (int i = 0; i < count; i++) 15 // { 16 // Input.Add(Rand.Next(int.MinValue, int.MaxValue)); 17 // } 18 Input.Add(1); Input.Add(2); Input.Add(3); Input.Add(4); Input.Add(5); Input.Add(19); 19 20 ulong re = PigeonNest(Input, ulong.MaxValue); 21 Console.WriteLine(re); 22 Console.WriteLine(ulong.MaxValue); 23 Console.WriteLine(Input.Min()); 24 } 25 26 //鸽巢原理。 27 static ulong PigeonNest(List<int> List, ulong MinResult) 28 { 29 switch (List.Count) 30 { 31 case 0: 32 case 1: 33 return MinResult; 34 case 2: 35 return ABS(List[0], List[1]); 36 default: 37 break; 38 } 39 int min = List.Min(); 40 //确定桶的大小。 41 int width = (int)Math.Ceiling((double)(List.Max() - min) / List.Count); 42 //不可能比1还小了。 43 if (width == 1) { return 1ul; } 44 //把数据丢到桶里。 45 Dictionary<int, NumbersInfo> EachNestNum = new Dictionary<int, NumbersInfo>(); 46 foreach (int n in List) 47 { 48 int Key = Convert.ToInt32(Math.Ceiling((double)(n - min) / width)); 49 if (!EachNestNum.ContainsKey(Key)) 50 { 51 EachNestNum.Add(Key, new NumbersInfo(Key)); 52 } 53 EachNestNum[Key].Add(n); 54 } 55 //找到所有桶里,和相邻两桶的最大最小值距离,三个数中最近的。 56 foreach (int Key in EachNestNum.Keys) 57 { 58 MinResult = Min(MinResult, EachNestNum[Key].minresult(EachNestNum, MinResult)); 59 } 60 return MinResult; 61 } 62 class NumbersInfo 63 { 64 public NumbersInfo(int k) 65 { key = k; } 66 private List<int> List = new List<int>(); 67 private int key; 68 public int max = int.MinValue; 69 public int min = int.MaxValue; 70 public int count { get { return List.Count; } } 71 public ulong minresult(Dictionary<int, NumbersInfo> EachNestNum, ulong re) 72 { 73 //在三个数中选最小的。 74 //当命中数大于1的时候,递归这个过程。由于迅速收敛,故复杂度忽略不计。 75 if (List.Count > 1) 76 { 77 re = PigeonNest(List, re); 78 } 79 if (EachNestNum.ContainsKey(key - 1)) 80 { 81 re = Min(ABS(EachNestNum[key].min, EachNestNum[key - 1].max), re); 82 } 83 if (EachNestNum.ContainsKey(key + 1)) 84 { 85 re = Min(ABS(EachNestNum[key].max, EachNestNum[key + 1].min), re); 86 } 87 return re; 88 } 89 public void Add(int x) 90 { 91 List.Add(x); 92 if (x > max) { max = x; } 93 if (x < min) { min = x; } 94 } 95 } 96 97 98 static ulong ABS(int x, int y) 99 { 100 //三分。 101 switch (x.CompareTo(y)) 102 { 103 case -1: 104 return (ulong)y - (ulong)x; 105 case 1: 106 return (ulong)x - (ulong)y; 107 } 108 return 0ul; 109 110 } 111 112 static ulong Min(ulong x, ulong y) 113 { 114 if (x > y) { return y; } 115 return x; 116 } 117 } 118 }
2、平面上N个点,没两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点
平面上N个点,没两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点(斜率不存在的情况不考虑)。时间效率越高越好。
先把N个点按x排序。
斜率k最大值为max(斜率(point[i],point[i+1])) 0 <=i <n-2。
复杂度Nlog(N)。
以3个点为例,按照x排序后为ABC,假如3点共线,则斜率一样,假如不共线,则可以证明AB或BC中,一定有一个点的斜率大于AC,一个点的斜率小于AC。
3、写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码编写出一个从字符串到长整型的函数)
1 long strtoint(char *str,int length){ 2 if(length > 1) { 3 return str[0]=='-' ? strtoint(str, length-1)*10-(str[length-1]-'0') : strtoint(str, length-1)*10+str[length-1]-'0'; 4 } else { 5 return str[0]=='-' ? -1/10 : str[0]-'0'; 6 } 7 }
4、怎样编写一个程序,把一个有序整数数组放到二叉树中?
1 #include <iostream> 2 3 using namespace std; 4 5 typedef struct Node 6 { 7 int v; 8 struct Node *lchild; 9 struct Node *rchild; 10 }Node; 11 12 void Insert(Node *&n, int v) { 13 if (NULL == n) 14 { 15 n = (Node*)malloc(sizeof(Node)); 16 n->v = v; n->lchild = n->rchild = NULL; 17 return; 18 } 19 if (v < n->v) 20 { 21 Insert(n->lchild, v); 22 } 23 else 24 { 25 Insert(n->rchild, v); 26 } 27 } 28 29 void Print(Node *r) 30 { 31 if (NULL == r) 32 { 33 return; 34 } 35 Print(r->lchild); 36 cout << r->v << endl; 37 Print(r->rchild); 38 } 39 40 Node *root = NULL; 41 42 void Print1(int a[], int low, int high) 43 { 44 if (low > high) return; 45 int mid = (low+high)/2; 46 Insert(root, mid); 47 Print1(a, low, mid-1); 48 Print1(a, mid+1, high); 49 } 50 51 int main() 52 { 53 // Node *root = NULL; 54 // for (int i = 0; i < 3; i++) 55 // { 56 // Insert(root, i); 57 // } 58 59 int a[6]; 60 for (int i = 0; i < 6; i++) 61 { 62 a[i] = i; 63 } 64 65 Print1(a, 0, 5); 66 67 // Êä³ö²éÕÒ¶þ²æÊ÷ 68 Print(root); 69 70 return 0; 71 }
5、怎样从顶部开始逐层打印二叉树结点数据?请编程。
1 void Print2(Node *root) 2 { 3 queue<Node*> q; 4 q.push(root); 5 6 while(!q.empty()) 7 { 8 Node *t = q.front(); 9 q.pop(); 10 cout << t->v; 11 if (t->lchild) q.push(t->lchild); 12 if (t->rchild) q.push(t->rchild); 13 } 14 cout << endl; 15 }
6、编程实现两个正整数的除法
1 #include <iostream> 2 3 using namespace std; 4 5 int div1(const int x, const int y) { 6 int left_num = x; 7 int result = 0; 8 while (left_num >= y) { 9 int multi = 1; 10 while (y * multi <= (left_num>>1)) { 11 multi = multi << 1; 12 } 13 result += multi; 14 left_num -= y * multi; 15 } 16 return result; 17 } 18 19 int main() 20 { 21 cout << div1(11, 3) << endl; 22 return 0; 23 }
7、在排序数组中,找出给定数字的出现次数。比如 [1, 2, 2, 2, 3] 中2的出现次数是3次。
1 #include <iostream> 2 3 using namespace std; 4 5 void equal_range1(int a[], int len, int x) 6 { 7 int low=0, high=len-1; 8 int mid; 9 while (low<=high) 10 { 11 mid=(low+high)/2; 12 if (x==a[mid]) {cout << mid << endl; break;} 13 else if (x<mid) high=mid-1; 14 else low=mid+1; 15 } 16 if (low>high) 17 { 18 cout << "ûÓÐÕÒµ½" << x << endl; 19 } 20 else 21 { 22 int k=mid-1; 23 while (k>=0&&a[k]==x) 24 { 25 cout << k-- << endl; 26 } 27 k=mid+1; 28 while (k<=len-1&&a[k]==x) 29 { 30 cout << k++ << endl; 31 } 32 } 33 } 34 35 int main() 36 { 37 int a[] = {1,2,2,2,2,3,4}; 38 equal_range1(a, 7, 2); 39 return 0; 40 }
8、一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
注意:
- 5个数值允许是乱序的。比如: 8 7 5 0 6
- 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4
- 0可以多次出现。
- 复杂度如果是O(n2)则不得分。
插入排序-》最大值-最小值<=4
9、一棵排序二叉树,令 f=(最大值+最小值)/2,设计一个算法,找出距离f值最近、大于f值的结点。复杂度如果是O(n2)则不得分。
1 void find1(Node *h, int value1, Node *&r)
2 {
3 if (NULL==h)
4 {
5 return;
6 }
7 if (value1 >= h->v)
8 {
9 find1(h->rchild, value1, r);
10 }
11 else
12 {
13 r=h;
14 find1(h->lchild, value1, r);
15 }
16 }