1、和为S的连续正数序列
Java实现:

package com.mian.algorithm; import java.util.ArrayList; public class FindContinuousSequence { public static void main(String[] args) { FindContinuousSequence continuousSequence=new FindContinuousSequence(); ArrayList<ArrayList<Integer>> list=continuousSequence.findContinuousSequence(100); for(int i=0;i<list.size();++i){ for(int j=0;j<list.get(i).size();++j){ System.out.print(list.get(i).get(j)+" "); } System.out.println(); } } private ArrayList<ArrayList<Integer>> findContinuousSequence(int sum){ ArrayList<ArrayList<Integer>> res=new ArrayList<ArrayList<Integer>>(); if(sum<=1){ return res; } int start=1; int end=2; while(start!=(1+sum)/2){ int curSum=(start+end)*(end-start+1)/2; if(curSum==sum){ ArrayList<Integer> list=new ArrayList<Integer>(); for(int i=start;i<=end;++i){ list.add(i); } res.add(list); ++start; ++end; }else if(curSum<sum){ ++end; }else{ ++start; } } return res; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<vector<int>> findContinuousSequence(int sum) 7 { 8 vector<vector<int>> res; 9 if (sum <= 1) 10 return res; 11 int start = 1; 12 int end = 2; 13 while (start != (1 + sum) / 2) 14 { 15 int curSum = (start + end)*(end - start + 1) / 2; 16 if (curSum == sum) 17 { 18 vector<int> tmp; 19 for (int i = start; i <= end; ++i) 20 tmp.push_back(i); 21 res.push_back(tmp); 22 tmp.clear(); 23 ++start; 24 ++end; 25 } 26 else if (curSum < sum) 27 ++end; 28 else 29 ++start; 30 } 31 return res; 32 } 33 34 int main() 35 { 36 vector<vector<int>> res = findContinuousSequence(100); 37 for (int i = 0; i < res.size(); ++i) 38 { 39 for (int j = 0; j < res[i].size(); ++j) 40 cout << res[i][j] << " "; 41 cout << endl; 42 } 43 44 return 0; 45 }
2、如何判断一个链表是否有环,如果有环,则返回第一个进入环的节点,没有则返回null。
第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈,有2x=n+x;n=x; 可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
Java实现:

package com.mian.algorithm; import java.util.Scanner; class ListNode{ int val; ListNode next; ListNode(){} ListNode(int x){ this.val=x; this.next=null; } } public class GetLoopNode { public static void main(String[] args){ GetLoopNode getLoopNode=new GetLoopNode(); ListNode head=getLoopNode.createList(); getLoopNode.printList(head); ListNode p=head.next.next; ListNode last=head; while(last.next!=null){ last=last.next; } last.next=p; ListNode node=getLoopNode.getLoopNode(head); System.out.println(node.val); } private ListNode getLoopNode(ListNode head){ if(head==null||head.next==null||head.next.next==null){ return null; } ListNode slow=head; ListNode fast=head; while(fast!=null&&fast.next!=null){ slow=slow.next; fast=fast.next.next; if(slow==fast){ fast=head; while(slow!=fast){ slow=slow.next; fast=fast.next; } return slow; } } return null; } private void printList(ListNode head){ if(head==null){ return; } ListNode p=head; while(p.next!=null){ System.out.print(p.val+" "); p=p.next; } System.out.println(p.val); } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list value (enter 100 to quit):"); Scanner sc=new Scanner(System.in); val=sc.nextInt(); if(val==100){ return head; }else{ head=new ListNode(val); head.next=createList(); } return head; } }
C++实现:

1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode 6 { 7 public: 8 int val; 9 ListNode* next; 10 ListNode() {} 11 ListNode(int x) :val(x), next(nullptr) {} 12 }; 13 14 ListNode* createNode() 15 { 16 int in; 17 ListNode* head = nullptr; 18 cout << "enter list value (enter 100 to quit):"; 19 cin >> in; 20 if (in == 100) 21 return head; 22 else 23 { 24 head = new ListNode(in); 25 head->next = createNode(); 26 } 27 return head; 28 } 29 30 void printList(ListNode* head) 31 { 32 if (head == nullptr) 33 return; 34 ListNode* p = head; 35 while (p) 36 { 37 cout << p->val << " "; 38 p = p->next; 39 } 40 cout << endl; 41 } 42 43 ListNode* getLoopNode(ListNode* head) 44 { 45 if (!head || !head->next || !head->next->next) 46 return head; 47 ListNode* n1 = head->next; 48 ListNode* n2 = head->next->next; 49 while (n1 != n2) 50 { 51 if (!n1->next || !n2->next->next) 52 return nullptr; 53 n1 = n1->next; 54 n2 = n2->next->next; 55 } 56 n2 = head; 57 while (n1 != n2) 58 { 59 n1 = n1->next; 60 n2 = n2->next; 61 } 62 return n1; 63 } 64 65 int main() 66 { 67 ListNode* head = createNode(); 68 printList(head); 69 ListNode* p = head->next->next; 70 ListNode* last = head; 71 while (last->next) 72 last = last->next; 73 last->next = p; 74 cout << getLoopNode(head)->val << endl; 75 76 return 0; 77 }
3、回文字符串
Java实现:

package com.mian.algorithm; public class IsPalindrome { public static void main(String[] args) { String str="abceda"; String str2=""; String str3="abdba"; boolean flag=isPalindrome(str3); System.out.println(flag); } private static boolean isPalindrome(String str){ int size=str.length(); if(size==0||str.isEmpty()){ return false; } int i=0; while(i<size/2){ if(str.charAt(i)!=str.charAt(size-i-1)){ return false; } ++i; } return true; } }
C++实现:

1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 bool isPalindrome(string &str) 7 { 8 int size = str.size(); 9 if (size == 0 || str.empty()) 10 return false; 11 int i = 0; 12 while (i < size / 2) 13 { 14 if (str[i] != str[size - i - 1]) 15 return false; 16 ++i; 17 } 18 return true; 19 } 20 21 int main() 22 { 23 string str = "abceba"; 24 cout << isPalindrome(str) << endl; 25 26 return 0; 27 }
4、不使用循环,判断一个数是否是2的N次方
凡是2的N次方的整数,其二进制码只有一个1
Java实现:

package com.mian.algorithm; public class Is2N { public static void main(String[] args) { boolean flag=is2N(16); System.out.println(flag); } private static boolean is2N(int n){ if((n>0)&&((n&(n-1))==0)){ return true; } return false; } }
C++实现:

1 bool is2N(int n) 2 { 3 if ((n > 0) && ((n&(n - 1)) == 0)) 4 return true; 5 return false; 6 }
5、求1!+2!+3!+4!+...+n!的结果。
Java实现:

package com.mian.algorithm; public class JieChengHe { public static void main(String[] args){ int res=jieChengHe(4); System.out.println(res); System.out.println(jieChengHeNoRec(4)); } private static long jieChengHeNoRec(int n){ long sum=0,num=1; for(int i=1;i<=n;++i){ num*=i; sum+=num; } return sum; } private static int jieChengHe(int n){ if(n==1){ return 1; } return jieChengHe(n-1)+jieCheng(n); } private static int jieCheng(int n){ if(n==1){ return 1; } return jieCheng(n-1)*n; } }
C++实现:

1 int jieCheng(int n) 2 { 3 if (n == 1) 4 return 1; 5 return n*jieCheng(n - 1); 6 } 7 8 int jieChengHe(int n) 9 { 10 if (n == 1) 11 return 1; 12 return jieChengHe(n - 1) + jieCheng(n); 13 }
6、N的阶乘末尾有多少个0
分析:N的阶乘可以分解为: 2的X次方,3的Y次方,4的K次方,5次Z方,.....的乘积。由于10 = 2 * 5,所以M只能和X和Z有关,每一对2和5相乘就可以得到一个10,于是M = MIN(X,Z),不难看出X大于Z,因为被2整除的频率比被5整除的频率高的多。所以可以把公式简化为M=Z。
Java实现:

package com.mian.algorithm; public class JieChengLastZero { public static void main(String[] args) { int res=jieChengLastZero(10); System.out.println(res); } private static int jieChengLastZero(int n){ if(n<0){ return 0; } int res=0; for(int i=5;i<=n;++i){ int j=i; while(j%5==0){ ++res; j=j/5; } } return res; } }
C++实现:

1 int jieChengLastZero(int n) 2 { 3 if (n < 0) 4 return; 5 int res = 0; 6 for (int i = 5; i <= n; ++i) 7 { 8 int j = i; 9 while (j % 5 == 0) 10 { 11 ++res; 12 j = j / 5; 13 } 14 } 15 return res; 16 }
7、在字符串中求最长数字子序列的长度
Java实现:

package com.mian.algorithm; public class LongestNumSubString { public static void main(String[] args){ String str="ad3299adfa3239028903afd"; System.out.println(longestNumSubString(str)); } private static int longestNumSubString(String str){ int size=str.length(); if(size==0||str.isEmpty()){ return 0; } int cnt=0; int num=0; for(int i=0;i<size;++i){ if(isNumber(str.charAt(i))){ ++cnt; if(cnt>num){ num=cnt; } }else{ cnt=0; } } return num; } private static boolean isNumber(char c){ int n=c-48; if(n>=0&&n<=9){ return true; } return false; } }
C++实现:

1 bool isNumber(char c) 2 { 3 int d = c - 48; 4 if (d >= 0 && d <= 9) 5 return true; 6 return false; 7 } 8 9 int longestNumSubString(string &str) 10 { 11 int size = str.size(); 12 if (str.empty() || size == 0) 13 return 0; 14 int max = 0; 15 int cnt = 0; 16 for (int i = 0; i < size; ++i) 17 { 18 if (isNumber(str[i])) 19 { 20 cnt++; 21 if (cnt > max) 22 max = cnt; 23 } 24 else 25 cnt = 0; 26 } 27 return max; 28 }
8、最长递增子序列
Java实现:

package com.mian.algorithm; public class LongestSequence { public static void main(String[] args) { int[] arr={ 4,1,2,5,0,3,6,8 }; int[] res=longestSequence(arr); for(int i=0;i<res.length;++i){ System.out.print(res[i]+" "); } } private static int[] longestSequence(int[] arr){ int size=arr.length; if(size==0||arr==null){ return null; } // 记录当前各元素作为最大元素的最长递增序列长度 int[] maxLen=new int[size]; // 记录当前以该元素作为最大元素的递增序列中该元素的前驱节点,用于打印序列用 int[] pre=new int[size]; for(int i=0;i<size;++i){ maxLen[i]=1; pre[i]=i; } int k=0; int m=1; for(int i=0;i<size;++i){ for(int j=0;j<i;++j){ if(arr[j]<arr[i]&&maxLen[j]+1>maxLen[i]){ maxLen[i]=maxLen[j]+1; pre[i]=j; } if(m<maxLen[i]){ m=maxLen[i]; k=i; } } } int i=m-1; int[] res=new int[m]; while(pre[k]!=k){ res[i--]=arr[k]; k=pre[k]; } res[i]=arr[k]; return res; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<int> longestSequence(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (arr.empty() || size == 0) 10 return vector<int>(); 11 // 记录当前各元素作为最大元素的最长递增序列长度 12 vector<int> maxLen(size); 13 // 记录当前以该元素作为最大元素的递增序列中该元素的前驱节点,用于打印序列用 14 vector<int> pre(size); 15 for (int i = 0; i < size; ++i) 16 { 17 maxLen[i] = 1; 18 pre[i] = i; 19 } 20 int k = 0; 21 int max = 1; 22 for (int i = 1; i < size; ++i) 23 { 24 // 找到以array[i]为最末元素的最长递增子序列 25 for (int j = 0; j < i; ++j) 26 { 27 //如果求非递减子序列只需将array[j] < array[i]改成<=,如果要求递减子序列只需改为> 28 if (arr[j]<arr[i] && maxLen[j] + 1>maxLen[i]) 29 { 30 maxLen[i] = maxLen[j] + 1; 31 pre[i] = j; 32 } 33 if (max < maxLen[i]) 34 { 35 max = maxLen[i]; 36 k = i; 37 } 38 } 39 } 40 int i = max - 1; 41 vector<int> res(max); 42 while (pre[k] != k) 43 { 44 res[i--] = arr[k]; 45 k = pre[k]; 46 } 47 res[i] = arr[k]; 48 return res; 49 } 50 51 int main() 52 { 53 vector<int> arr{ 4,1,2,5,0,3,6,8 }; 54 vector<int> res = longestSequence(arr); 55 for (int i = 0; i < res.size(); ++i) 56 cout << res[i] << " "; 57 cout << endl; 58 59 return 0; 60 }
9、最长连续递增子序列的长度
Java实现:

package com.mian.algorithm; public class LongestSerialSequence { public static void main(String[] args) { int[] arr={ 4,1,2,5,0,3,6,8 }; System.out.println(longestSerialSequence(arr)); } private static int longestSerialSequence(int[] arr){ int size=arr.length; if(size==0||arr==null){ return 0; } int curLen=1; int resLen=1; for(int i=1;i<size;++i){ if(arr[i-1]<arr[i]){ ++curLen; if(curLen>resLen){ resLen=curLen; } }else{ curLen=1; } } int cur=1; for(int i=size-1;i>0;--i){ if(arr[i]<arr[i-1]){ ++cur; if(cur>resLen){ resLen=cur; } }else{ cur=1; } } return resLen; } }
C++实现:

1 int longestSerialSequence(vector<int> &arr) 2 { 3 int size = arr.size(); 4 if (size == 0 || arr.empty()) 5 return -1; 6 int curLen = 1; 7 int resLen = 1; 8 for (int i = 1; i < size; ++i) 9 { 10 if (arr[i] > arr[i - 1]) 11 curLen++; 12 else 13 curLen = 1; 14 if (curLen > resLen) 15 resLen = curLen; 16 } 17 curLen = 1; 18 for (int i = size - 1; i >= 1; --i) 19 { 20 if (arr[i] < arr[i - 1]) 21 curLen++; 22 else 23 curLen = 1; 24 if (curLen > resLen) 25 resLen = curLen; 26 } 27 return resLen; 28 }
10、打印最长连续递增子序列
Java实现:

package com.mian.algorithm; public class PrintLongestSerialSequence { public static void main(String[] args) { int[] arr={ 4,1,2,5,0,3,6,8 }; printLongestSerialSequence(arr); } private static void printLongestSerialSequence(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } int curLen=1; int resLen=1; int index=0; for(int i=1;i<size;++i){ if(arr[i]>arr[i-1]){ ++curLen; if(curLen>resLen){ resLen=curLen; index=i; } }else{ curLen=1; } } int i=index-resLen+1; while(resLen!=0){ System.out.print(arr[i]+" "); ++i; --resLen; } } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 void longestSerialSequence(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return; 11 int curLen = 1; 12 int resLen = 1; 13 int index = 0; 14 for (int i = 1; i < size; ++i) 15 { 16 if (arr[i] > arr[i - 1]) 17 { 18 curLen++; 19 index = i; 20 } 21 else 22 curLen = 1; 23 if (curLen > resLen) 24 resLen = curLen; 25 } 26 int i = index - resLen + 1; 27 while (resLen) 28 { 29 cout << arr[i] << " "; 30 ++i; 31 --resLen; 32 } 33 cout << endl; 34 } 35 36 int main() 37 { 38 vector<int> kk = { 2, 13, 6, 8, 9, 1 }; 39 longestSerialSequence(kk); 40 41 return 0; 42 }
11、最小的K个数
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
Java实现:

package com.mian.algorithm; public class FindLowestK { public static void main(String[] args) { int[] arr={ 4, 5, 1, 6, 2, 7, 3, 8 }; FindLowestK fk=new FindLowestK(); int[] res=fk.findLowestK(arr,3); fk.printArray(res); int[] part=fk.findLowestKP(arr,3); fk.printArray(part); } //方法一:最大堆 时间复杂度O(nlogk) private int[] findLowestK(int[] arr,int k){ int size=arr.length; if(size==0||arr==null||size<k||k<=0){ return null; } int[] res=new int[k]; for(int i=0;i<k;++i){ res[i]=arr[i]; } heapSort(res); for(int i=k;i<size;++i){ if(res[k-1]>arr[i]){ res[k-1]=arr[i]; heapSort(res); } } return res; } private void heapSort(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=size/2-1;i>=0;--i){ adjustMaxHeap(arr,i,size); } for(int i=size-1;i>0;--i){ swap(arr,0,i); adjustMaxHeap(arr,0,--size); } } private void adjustMaxHeap(int[] arr,int i,int size){ int left=2*i+1; int right=2*i+2; int largest=i; if(left<size&&arr[left]>arr[largest]){ largest=left; } if(right<size&&arr[right]>arr[largest]){ largest=right; } if(largest!=i){ swap(arr,i,largest); adjustMaxHeap(arr,largest,size); } } private void swap(int[] arr,int i,int j){ int tmp=arr[i]; arr[i]=arr[j]; arr[j]=tmp; } //方法二:Partiton思想 时间复杂度O(n) private int[] findLowestKP(int[] arr,int k){ int size=arr.length; if(size==0||arr==null){ return null; } int low=0; int high=size-1; int index=partition(arr,low,high); while(index!=(k-1)){ if(index>(k-1)){ high=index-1; index=partition(arr,low,high); }else if(index<(k-1)){ low=index+1; index=partition(arr,low,high); } } int[] res=new int[k]; System.arraycopy(arr,0,res,0,k); return res; } private int partition(int[] arr,int low,int high){ int pivot=arr[low]; while(low<high){ while(low<high&&arr[high]>=pivot){ --high; } arr[low]=arr[high]; while(low<high&&arr[low]<=pivot){ ++low; } arr[high]=arr[low]; } arr[low]=pivot; return low; } private void printArray(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=0;i<size-1;++i){ System.out.print(arr[i]+" "); } System.out.println(arr[size-1]); } }
C++实现:

#include<iostream> #include<vector> #include<multiset> using namespace std; //方法一:最大堆 时间复杂度O(nlogk) void swap(vector<int> &arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } void adjustMaxHeap(vector<int> &arr, int i, int size) { int left = 2 * i + 1; int right = 2 * i + 2; int largest = i; if (left<size&&arr[left]>arr[largest]) largest = left; if (right<size&&arr[right]>arr[largest]) largest = right; if (largest != i) { swap(arr, largest, i); adjustMaxHeap(arr, largest, size); } } void heapSort(vector<int> &arr) { int size = arr.size(); if (arr.empty() || size == 0) return; for (int i = size / 2 - 1; i >= 0; --i) adjustMaxHeap(arr, i, size); for (int j = size - 1; j > 0; --j) { swap(arr, 0, j); adjustMaxHeap(arr, 0, --size); } } vector<int> findLowestK(vector<int> &arr, int k) { int size = arr.size(); if (arr.empty() || size == 0 || size < k || k <= 0) return vector<int>(); vector<int> res(k); /* vector<int>::iterator it = arr.begin(); copy(it, it+k,res); */ for (int i = 0; i < k; ++i) res[i] = arr[i]; heapSort(res); for (int i = k; i < size; ++i) if (arr[i] < res[k - 1]) { res[k - 1] = arr[i]; heapSort(res); } return res; } //方法二:Partiton思想 时间复杂度O(n) int partition(vector<int> &arr, int low, int high) { int pivot = arr[low]; while (low < high) { while (low < high&&pivot <= arr[high]) --high; arr[low] = arr[high]; while (low < high&&pivot >= arr[low]) ++low; arr[high] = arr[low]; } arr[low] = pivot; return low; } vector<int> findLowestK2(vector<int> &arr, int k) { int size = arr.size(); if (size == 0 || arr.empty() || size < k || k <= 0) return vector<int>(); int low = 0; int high = size - 1; int index = partition(arr, low, high); while (index != (k - 1)) { if (index > (k - 1)) { high = index - 1; partition(arr, low, high); } else { low = index + 1; partition(arr, low, high); } } return vector<int>(arr.begin(), arr.begin() + k); } //方法三:红黑树:multiset集合 利用仿函数改变排序顺序 时间复杂度O(nlogk) vector<int> findLowestK3(vector<int> &arr, int k) { int size = arr.size(); if (size <= 0 || size < k || k <= 0) return vector<int>(); //仿函数中的greater<T>模板,从大到小排序 multiset<int, greater<int> > leastNums; vector<int>::iterator vec_it = input.begin(); for (; vec_it != input.end(); vec_it++) { //将前k个元素插入集合 if (leastNums.size()<k) leastNums.insert(*vec_it); else { //第一个元素是最大值 multiset<int, greater<int> >::iterator greatest_it = leastNums.begin(); //如果后续元素<第一个元素,删除第一个,加入当前元素 if (*vec_it<*(leastNums.begin())) { leastNums.erase(greatest_it); leastNums.insert(*vec_it); } } } return vector<int>(leastNums.begin(), leastNums.end()); } int main() { vector<int> ay = { 4, 5, 1, 6, 2, 7, 3, 8 }; vector<int> fi = findLowestK(ay, 4); for (int i = 0; i < fi.size(); ++i) cout << fi[i] << " "; cout << endl; vector<int> fi2 = findLowestK2(ay, 4); for (int i = 0; i < fi2.size(); ++i) cout << fi[i] << " "; cout << endl; vector<int> fi3 = findLowestK3(ay, 4); for (int i = 0; i < fi3.size(); ++i) cout << fi[i] << " "; cout << endl; return 0; }
12、没有优先级的"+","-","x"
Java实现:

package com.mian.algorithm; import java.util.Scanner; public class NoPriority { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String str=sc.nextLine(); int res=noPriority(str); System.out.println(res); } private static int noPriority(String str){ int size=str.length(); if(size==0||str.isEmpty()){ return 0; } int res=str.charAt(0)-'0'; for(int i=1;i<size;++i){ int cur=str.charAt(i)-'0'; if(cur>=0&&cur<=9){ char pre=str.charAt(i-1); if(pre=='+'){ res+=cur; }else if(pre=='-'){ res-=cur; }else if(pre=='*'){ res*=cur; } } } return res; } }
C++实现:

1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 void noPriority() 7 { 8 cout << "Enter a string:"; 9 string str; 10 cin >> str; 11 int size = str.size(); 12 if (str.empty()|| size == 0) 13 return; 14 int res = str[0] - '0'; 15 for (int i = 1; i < size; i++) { 16 int cur = str[i] - '0'; 17 if (0 <= cur && cur <= 9) { 18 char pre = str[i-1]; 19 if (pre == '+') { 20 res += cur; 21 } 22 else if (pre == '-') { 23 res -= cur; 24 } 25 else { 26 res *= cur; 27 } 28 } 29 } 30 cout << res << endl; 31 } 32 33 int main() 34 { 35 noPriority(); 36 37 return 0; 38 }
13、在不使用循环的条件下,如何计算出一个数其2的n次方的最大数字(这个比较绕,例如17-->16,31-- >16)。
Java实现:

package com.mian.algorithm; public class Max2N { public static void main(String[] args) { System.out.println(max2N(31)); } private static int max2N(int n){ if((n>0)&&(n&(n-1))==0){ return n; } return max2N(n-1); } }
C++实现:

1 #include<iostream> 2 3 using namespace std; 4 5 int max2N(int n) 6 { 7 if ((n > 0) && (n&(n - 1)) == 0) 8 return n; 9 return max2N(n - 1); 10 } 11 12 int main() 13 { 14 cout << max2N(31) << endl; 15 16 return 0; 17 }
14、未排序数组中累加和为给定值的最长子数组的长度
Java实现:

package com.mian.algorithm; import java.util.HashMap; public class MaxLength { public static void main(String[] args) { int[] arr={ 1,2,1,1,1 }; int target=3; System.out.println(maxLength(arr,target)); System.out.println(maxLength2(arr,target)); } /** * 0到位置i的累加和我们用sum[0~i],存在j使得sum[0~j] - sum[0~i] = k,则k = sum[i+1~j] * 补充题目1:给定一个无序数组 arr,其中元素可正、可负、可 0。 * 求 arr 所有的子数组中正数与负数个数相等的最长子数组长度。 * 要求:时间复杂度 O(N) * 分析:将数组中的正数变成1,负数变成-1,零仍然为零。然后求累加和为0的最长子数组, * 这样就将这个问题转化成未排序数组中累加和为给0的最长子数组问题了。 * 补充题目2:给定一个无序数组 arr,其中元素只是 1 或 0。求 arr 所有的子数组中 0 和 1 个 数相等的最长子数组长度。 * 要求:时间复杂度 O(N) * 分析:将数组中的0变成-1,1仍然为1,求累加和为0的最长子数组,可以求出1和-1个数相同,代表着0和1个数相同。 * * 方法一: */ private static int maxLength(int[] arr,int target){ int size=arr.length; if(size==0||arr==null){ return 0; } HashMap<Integer,Integer> map=new HashMap<>(); map.put(0,-1); int len=0; int sum=0; for(int i=0;i<size;++i){ sum+=arr[i]; if(map.containsKey(sum-target)){ len=(i-map.get(sum-target))>len?(i-map.get(sum-target)):len; } if(!map.containsKey(sum)){ map.put(sum,i); } } return len; } /** * 方法二:使用两个指针left和right,记录从left到right之间的元素的值得和,使用一个变量len记录长度。 * 如果这个和大于目标,那么left加1,如果这个和小于目标,那么right加1,如果这个值等于目标,那么比较并更新len, * 同时left++。right超过最右边的时候结束循环。 */ private static int maxLength2(int[] arr,int target){ int size=arr.length; if(size==0||arr==null){ return 0; } int left=0; int right=0; int len=0; int sum=0; while(right<size){ if(sum<target){ ++right; if(right==size){ break; } sum+=arr[right]; }else if(sum>target){ sum+=arr[left++]; }else{ len=Math.max(len,right-left+1); sum-=arr[left++]; } } return len; } }
C++实现:
0到位置i的累加和我们用sum[0~i],存在j使得sum[0~j] - sum[0~i] = k,则k = sum[i+1~j]
补充题目1:给定一个无序数组 arr,其中元素可正、可负、可 0。求 arr 所有的子数组中正数与负数个数相等的最长子数组长度。
要求:时间复杂度 O(N)
分析:将数组中的正数变成1,负数变成-1,零仍然为零。然后求累加和为0的最长子数组,这样就将这个问题转化成未排序数组中累加和为给0的最长子数组问题了。
补充题目2:给定一个无序数组 arr,其中元素只是 1 或 0。求 arr 所有的子数组中 0 和 1 个 数相等的最长子数组长度。
要求:时间复杂度 O(N)
分析:将数组中的0变成-1,1仍然为1,求累加和为0的最长子数组,可以求出1和-1个数相同,代表着0和1个数相同。
方法一:

1 #include<iostream> 2 #include<vector> 3 #include<unordered_map> 4 #include<algorithm> 5 6 using namespace std; 7 8 int maxLength(vector<int> &arr, int target) 9 { 10 int size = arr.size(); 11 if (size == 0 || arr.empty()) 12 return 0; 13 unordered_map<int, int> m; 14 m[0] = -1; 15 int len = 0; 16 int sum = 0; 17 for (int i = 0; i < size; ++i) 18 { 19 sum += arr[i]; 20 auto it = m.find(sum - target); 21 if (it != m.end()) 22 len = (i - m[sum - target]) > len ? (i - m[sum - target]) : len; 23 auto p = m.find(sum); 24 if (p == m.end()) 25 m[sum] = i; 26 } 27 return len; 28 } 29 30 int main() 31 { 32 vector<int> arr = { 1,2,1,1,1 }; 33 int target = 3; 34 cout << maxLength(arr, target) << endl; 35 36 return 0; 37 }
方法二:使用两个指针left和right,记录从left到right之间的元素的值得和,使用一个变量len记录长度。如果这个和大于目标,那么left加1,如果这个和小于目标,那么right加1,如果这个值等于目标,那么比较并更新len,同时left++。right超过最右边的时候结束循环。

1 #include<iostream> 2 #include<vector> 3 #include<unordered_map> 4 #include<algorithm> 5 6 using namespace std; 7 8 int maxLen(vector<int> &arr, int target) 9 { 10 int size = arr.size(); 11 if (size == 0 || arr.empty()) 12 return 0; 13 int left = 0, right = 0; 14 int sum = 0; 15 int len = 0; 16 while (right < size) 17 { 18 if (sum < target) 19 { 20 ++right; 21 if (right == size) 22 break; 23 sum += arr[right]; 24 } 25 else if (sum > target) 26 sum += arr[left++]; 27 else 28 { 29 len = max(len, right - left + 1); 30 sum -= arr[left++]; 31 } 32 } 33 return len; 34 } 35 36 int main() 37 { 38 vector<int> arr = { 1,2,1,1,1 }; 39 int target = 3; 40 cout << maxLen(arr, target) << endl; 41 42 return 0; 43 }
15、连续子序列的最大和
Java实现:

package com.mian.algorithm; public class MaxSum { public static void main(String[] args) { int[] arr={ 6,-3,-2,7,-15,1,2,2 }; System.out.println(maxSum(arr)); System.out.println(maxSum2(arr)); } /** * 方法一:连续子序列的最大和只可能是以位置0~n-1中某个位置结尾。当遍历到第i个元素时, * 判断在它前面的连续子序列和是否大于0,如果大于0,则以位置i结尾的最大连续子序列和为元素i和前门的连续子序列和相加; * 否则,则以位置i结尾的最大连续子序列和为元素i。 */ private static int maxSum(int[] arr){ int size=arr.length; if(size==0||arr==null){ return 0; } int curSum=arr[0]; int maxSum=arr[0]; for(int i=1;i<size;++i){ if(curSum<0){ curSum=arr[i]; }else{ curSum+=arr[i]; } if(curSum>maxSum){ maxSum=curSum; } } return maxSum; } /** * 方法二:暴力解。时间复杂度O(n^2),空间复杂度O(1)。 */ private static int maxSum2(int[] arr){ int size=arr.length; if(size==0||arr==null){ return 0; } int maxSum=Integer.MIN_VALUE; for(int i=0;i<size;++i){ int curSum=0; for(int j=i;j<size;++j){ curSum+=arr[j]; if(curSum>maxSum){ maxSum=curSum; } } } return maxSum; } }
C++实现:
方法一:连续子序列的最大和只可能是以位置0~n-1中某个位置结尾。当遍历到第i个元素时,判断在它前面的连续子序列和是否大于0,如果大于0,则以位置i结尾的最大连续子序列和为元素i和前门的连续子序列和相加;否则,则以位置i结尾的最大连续子序列和为元素i。

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 int maxSum(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return -1; 11 int max = arr[0]; 12 int cur = arr[0]; 13 for (int i = 1; i < size; ++i) 14 { 15 if (cur <= 0) 16 cur = arr[i]; 17 else 18 cur += arr[i]; 19 if (cur > max) 20 max = cur; 21 } 22 return max; 23 } 24 25 int main() 26 { 27 vector<int> arr = { 6,-3,-2,7,-15,1,2,2 }; 28 cout << maxSum(arr) << endl; 29 30 return 0; 31 }
方法二:暴力解。时间复杂度O(n^2),空间复杂度O(1)。

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 int maxSum(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return -1; 11 int max = INT_MIN; 12 for (int i = 0; i < size; ++i) 13 { 14 int sum = 0; 15 for (int j = i; j < size; ++j) 16 { 17 sum += arr[j]; 18 if (sum > max) 19 max = sum; 20 } 21 } 22 return max; 23 } 24 25 int main() 26 { 27 vector<int> arr = { 6,-3,-2,7,-15,1,2,2 }; 28 cout << maxSum(arr) << endl; 29 30 return 0; 31 }
16、合并两个有序数组
Java实现:

package com.mian.algorithm; public class MergeArray { public static void main(String[] args) { int[] arr1={ 0,3,5,6,7,9 }; int[] arr2= { 2,3,4,7,8,9 }; int[] res=mergeArray(arr1,arr2); printArray(res); int[] res2=mergeArray2(arr1,arr2); printArray(res2); } private static int[] mergeArray(int[] arr1,int[] arr2){ int size1=arr1.length; int size2=arr2.length; if(size1==0||arr1==null){ return arr2; } if(size2==0||arr2==null){ return arr1; } if((size1==0&&size2==0)||(arr1==null&&arr2==null)){ return null; } int i=0,j=0,k=0; int[] res=new int[size1+size2]; while (i<size1&&j<size2){ if(arr1[i]<arr2[j]){ res[k++]=arr1[i++]; }else{ res[k++]=arr2[j++]; } } while(i<size1){ res[k++]=arr1[i++]; } while(j<size2){ res[k++]=arr2[j++]; } return res; } private static int[] mergeArray2(int[] arr1,int[] arr2){ int size1=arr1.length; int size2=arr2.length; if(size1==0||arr1==null){ return arr2; } if(size2==0||arr2==null){ return arr1; } if((size1==0&&size2==0)||(arr1==null&&arr2==null)){ return null; } int i=0,j=0,k=0; int[] res=new int[size1+size2]; while(i<size1&&j<size2){ if(arr1[i]<arr2[j]){ res[k++]=arr1[i++]; }else if(arr1[i]>arr2[j]){ res[k++]=arr2[j++]; }else{ res[k++]=arr1[i++]; res[k++]=arr2[j++]; } } while(i<size1){ res[k++]=arr1[i++]; } while(j<size2){ res[k++]=arr2[j++]; } return res; } private static void printArray(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=0;i<size-1;++i){ System.out.print(arr[i]+" "); } System.out.println(arr[size-1]); } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<int> mergeArray(vector<int> &arr1, vector<int> &arr2) 7 { 8 int size1 = arr1.size(); 9 int size2 = arr2.size(); 10 if (size1 == 0 || size2 == 0 || arr1.empty() || arr2.empty()) 11 return vector<int>(); 12 vector<int> res(size1 + size2); 13 int i = 0, j = 0, k = 0; 14 while (i < size1&&j < size2) 15 { 16 if (arr1[i] < arr2[j]) 17 res[k++] = arr1[i++]; 18 else if (arr1[i] > arr2[j]) 19 res[k++] = arr2[j++]; 20 else 21 { 22 res[k++] = arr1[i++]; 23 res[k++] = arr2[j++]; 24 } 25 } 26 while (i < size1) 27 res[k++] = arr1[i++]; 28 while (j < size2) 29 res[k++] = arr2[j++]; 30 return res; 31 } 32 33 int main() 34 { 35 vector<int> arr1 = { 0,3,5,6,7,9 }; 36 vector<int> arr2 = { 2,3,4,7,8,9 }; 37 vector<int> res = mergeArray(arr1, arr2); 38 for (int i = 0; i < res.size(); ++i) 39 cout << res[i] << " "; 40 cout << endl; 41 42 return 0; 43 }
17、旋转数组的最小数字
Java实现:

package com.mian.algorithm; public class MinNumberInRotateArray { public static void main(String[] args) { int[] arr={1,0,1,1,1}; System.out.println(minNumberInRotateArray(arr)); } private static int minNumberInRotateArray(int[] arr){ int size=arr.length; if(size==0||arr==null){ return 0; } int low=0; int high=size-1; int mid=low; while(arr[low]>=arr[high]){ if(high-low==1){ mid=high; break; } mid=(low+high)>>1; if(arr[low]==arr[mid]&&arr[mid]==arr[high]){ int min=arr[low]; for(int i=low+1;i<=high;++i){ if(min>arr[i]){ min=arr[i]; } } return min; }else if(arr[low]>=arr[mid]){ low=mid; }else if(arr[mid]<=arr[high]){ high=mid; } } return arr[mid]; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 int minNumberInRotateArray(vector<int> arr) { 7 int low = 0; 8 int high = arr.size() - 1; 9 int mid = low; 10 while (arr[low] >= arr[high]) 11 { 12 if (high - low == 1) 13 { 14 mid = high; 15 break; 16 } 17 mid = (low + high) / 2; 18 if (arr[low] == arr[mid] && arr[mid] == arr[high]) 19 { 20 int min = arr[low]; 21 for (int i = low + 1; i <= high; ++i) 22 if (min>arr[i]) 23 min = arr[i]; 24 return min; 25 } 26 if (arr[mid] >= arr[low]) 27 low = mid; 28 else if (arr[mid] <= arr[high]) 29 high = mid; 30 } 31 return arr[mid]; 32 } 33 34 int main() 35 { 36 vector<int> arr = {1,0,1,1,1}; 37 cout << minNumberInRotateArray(arr) << endl; 38 39 return 0; 40 }
18、数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
Java实现:

package com.mian.algorithm; import java.util.HashMap; public class MoreHalf { public static void main(String[] args) { int[] arr={1,2,3,2,2,2,5,4,2}; System.out.println(moreHalf(arr)); System.out.println(moreHalf2(arr)); System.out.println(moreHalf3(arr)); } private static int moreHalf(int[] arr){ int size=arr.length; if(size==0||arr==null){ return Integer.MIN_VALUE; } int cnt=0; int res=0; for(int i=0;i<size;++i){ if(cnt==0){ res=arr[i]; ++cnt; }else{ if(res==arr[i]){ ++cnt; }else{ --cnt; } } } cnt=0; for(int i=0;i<size;++i){ if(arr[i]==res){ ++cnt; } } if(cnt>size/2){ return res; } return Integer.MIN_VALUE; } private static int moreHalf2(int[] arr){ int size=arr.length; if(size==0||arr==null){ return Integer.MIN_VALUE; } int res=Integer.MIN_VALUE; HashMap<Integer,Integer> map=new HashMap<>(); for(int i=0;i<size;++i){ if(map.containsKey(arr[i])){ map.put(arr[i],map.get(arr[i])+1); }else{ map.put(arr[i],1); } if(map.get(arr[i])>size/2){ res=arr[i]; } } int cnt=0; for(int i=0;i<size;++i){ if(arr[i]==res){ ++cnt; } } if(cnt>size/2){ return res; } return Integer.MIN_VALUE; } private static int moreHalf3(int[] arr){ int size=arr.length; if(size==0||arr==null){ return Integer.MIN_VALUE; } int mid=size>>1; int low=0; int high=size-1; int index=partition(arr,low,high); while(index!=mid){ if(index>mid){ high=index-1; index=partition(arr,low,high); }else if(index<mid){ low=index+1; index=partition(arr,low,high); } } int res=arr[mid]; int cnt=0; for(int i=0;i<size;++i){ if(arr[i]==res){ ++cnt; } } if(2*cnt>size){ return res; }else{ return Integer.MIN_VALUE; } } private static int partition(int[] arr,int low,int high){ int pivot=arr[low]; while(low<high){ while(low<high&&arr[high]>=pivot){ --high; } arr[low]=arr[high]; while(low<high&&arr[low]<=pivot){ ++low; } arr[high]=arr[low]; } arr[low]=pivot; return low; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 int moreHalf(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return -1; 11 int candi = 0; 12 int cnt = 0; 13 for (int i = 0; i < size; ++i) 14 { 15 if (cnt == 0) 16 { 17 candi = arr[i]; 18 ++cnt; 19 } 20 else 21 { 22 if (arr[i] == candi) 23 ++cnt; 24 else 25 --cnt; 26 } 27 } 28 return candi; 29 } 30 31 int main() 32 { 33 vector<int> arr = { 8,0,2,3,1,2,2,1,2,2 }; 34 cout << moreHalf(arr) << endl; 35 36 return 0; 37 }
19、某一范围内的整数包含1的数量
Java实现:

package com.mian.algorithm; public class NumberOf1Between1AndN { public static void main(String[] args) { System.out.println(numberOf1Between1AndN(34278)); System.out.println(numberOf1Between1AndN2(34278)); } /** * 方法一:暴力解 */ private static int numberOf1Between1AndN(int n){ if(n<0){ return 0; } if(n<9){ return 1; } int cnt=1; for(int i=10;i<=n;++i){ int tmp=i; while(tmp!=0){ if(tmp%10==1){ ++cnt; } tmp/=10; } } return cnt; } private static int numberOf1Between1AndN2(int n){ int cnt = 0; for (int m = 1; m <= n; m *= 10){ int a = n / m, b = n%m; if (a % 10 == 0){ cnt+=a/10*m; }else if (a % 10 == 1) { cnt += a / 10 * m + (b + 1); }else{ cnt += (a / 10 + 1)*m; } } return cnt; } }
C++实现:
方法一:暴力解

1 #include<iostream> 2 3 using namespace std; 4 5 int NumberOf1Between1AndN(int n) 6 { 7 if (n <= 0) 8 return 0; 9 if (n < 9) 10 return 1; 11 int cnt = 1; 12 for (int i = 10; i <= n; ++i) 13 { 14 int tmp = i; 15 while (tmp) 16 { 17 if (tmp % 10 == 1) 18 ++cnt; 19 tmp /= 10; 20 } 21 } 22 return cnt; 23 } 24 25 int main() 26 { 27 cout << NumberOf1Between1AndN(34278) << endl; 28 29 return 0; 30 }
方法二:

1 #include<iostream> 2 3 using namespace std; 4 5 int NumberOf1Between1AndN(int n) 6 { 7 int cnt = 0; 8 for (int m = 1; m <= n; m *= 10) 9 { 10 int a = n / m, b = n%m; 11 if (a % 10 == 0) 12 cnt += a / 10 * m; 13 else if (a % 10 == 1) 14 cnt += a / 10 * m + (b + 1); 15 else 16 cnt += (a / 10 + 1)*m; 17 } 18 return cnt; 19 } 20 21 int main() 22 { 23 cout << NumberOf1Between1AndN(34278) << endl; 24 25 return 0; 26 }
20、N的阶乘二进制表示的最低位1的位置
这个问题实际上等同于求N!含有质因数2的个数+1。即答案等于N!含有质因数2的个数加1。 如果一个质数是某个数的因数,那么就说这个质数是这个数的质因数。
因为每存在一个2,则在数的最低位多1个0。实际上N!都为偶数,因为质因数里面都有一个2,
除了1以外,因为1的阶乘是1,是个奇数,其他数的阶乘都是偶数。
Java实现:

package com.mian.algorithm; public class PosOfOneBinary { public static void main(String[] args) { System.out.println(posOfOneBinary(3)); } private static int posOfOneBinary(int n){ if(n<0){ return -1; } int res=0; while(n!=0){ n>>=1; res+=n; } return (res+1); } }
C++实现:

1 #include<iostream> 2 3 using namespace std; 4 5 int posOfOneBinary(int n) 6 { 7 if (n < 0) 8 return -1; 9 int res = 0; 10 while (n) 11 { 12 n >>= 1; 13 res += n; 14 } 15 16 return (res + 1); 17 } 18 19 int main() 20 { 21 cout << posOfOneBinary(3) << endl; 22 23 return 0; 24 }
21、输入一个正整数N,输出大于N且最接近这个数的素数
Java实现:

package com.mian.algorithm; public class FindPrime { public static void main(String[] args) { FindPrime findPrime=new FindPrime(); findPrime.findPrime(34); } private static void findPrime(int n){ if(n<=1){ System.out.println(2); } while(n>0){ if(!isPrime(n)){ ++n; }else{ System.out.println(n); break; } } } private static boolean isPrime(int n){ if(n==0||n==1){ return false; } for(int i=2;i<Math.sqrt(n);++i){ if(n%i==0){ return false; } } return true; } }
C++实现:

1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 bool isPrime(int n) 7 { 8 if (n == 0 || n == 1) 9 return false; 10 for (int i = 2; i <= sqrt(n); ++i) 11 if (n%i == 0) 12 return false; 13 return true; 14 } 15 16 void findPrime(int n) 17 { 18 if (n <= 0) 19 return; 20 while (n > 0) 21 if (!isPrime(n)) 22 ++n; 23 else 24 { 25 cout << n << endl; 26 break; 27 } 28 } 29 30 int main() 31 { 32 findPrime(34); 33 34 return 0; 35 }
22、读取文件,每一行有一个字段为数字,按数字大小排序,输出整个文档
Java实现:

package com.mian.algorithm; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class ReadWriteFile { public static void main(String[] args)throws IOException{ ReadWriteFile rwf=new ReadWriteFile(); rwf.readWriteFile("D:/lina/in.txt","D:/lina/out.txt"); } private void readWriteFile(String in,String out){ File inFile=null; BufferedReader br=null; List<Integer> nums=new ArrayList<>(); try{ inFile=new File(in); if(!inFile.exists()||inFile.isDirectory()){ System.out.println("读入文件不存在!!!"); } br=new BufferedReader(new FileReader(inFile)); String tmp=br.readLine(); while(tmp!=null){ nums.add(Integer.parseInt(tmp)); System.out.print(tmp+" "); tmp=br.readLine(); } }catch (IOException e){ e.printStackTrace(); }finally { try { br.close(); }catch (IOException e){ e.printStackTrace(); } } Collections.sort(nums,(a,b)->a.compareTo(b)); BufferedWriter bw = null; try { File file = new File(out); if (!file.exists()) { file.createNewFile(); } FileWriter fw = new FileWriter(file.getAbsoluteFile()); bw = new BufferedWriter(fw); for(int i=0;i<nums.size();++i){ bw.write(nums.get(i).toString()); } } catch (IOException e) { e.printStackTrace(); }finally { try { bw.close(); }catch (IOException e){ e.printStackTrace(); } } } }
C++实现:

1 #include<iostream> 2 #include<fstream> 3 #include<vector> 4 #include<algorithm> 5 #include<string> 6 7 using namespace std; 8 9 void readWriteFile(string &in,string &out) 10 { 11 ifstream infile(in); 12 if (!infile.is_open()) 13 { 14 cout << "can not open" << in << endl; 15 EXIT_FAILURE; 16 } 17 vector<int> res; 18 int tmp; 19 while (!infile.eof()) 20 { 21 infile >> tmp; 22 res.push_back(tmp); 23 } 24 infile.close(); 25 sort(res.begin(), res.end()); 26 for (int i = 0; i < res.size(); ++i) 27 cout << res[i] << " "; 28 cout << endl; 29 ofstream outfile(out, 'w'); 30 if (!outfile.is_open()) 31 { 32 cout << "can not open" << out << endl; 33 EXIT_FAILURE; 34 } 35 vector<int>::iterator it = res.begin(); 36 while (it != res.cend()) 37 outfile << *it++; 38 outfile.close(); 39 } 40 41 int main() 42 { 43 string in = "num.txt"; 44 string out = "sort.txt"; 45 readWriteFile(in, out); 46 }
23、找出数组中重复的数
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
Java实现:

package com.mian.algorithm; import java.util.ArrayList; import java.util.List; public class DuplicateNum { public static void main(String[] args) { DuplicateNum dn=new DuplicateNum(); int[] arr={ 2,3,1,0,2,5,3 }; List<Integer> res=dn.duplicateNum(arr); for(int i=0;i<res.size();++i){ System.out.print(res.get(i)+" "); } } private List<Integer> duplicateNum(int[] arr){ int size=arr.length; if(size==0||arr==null){ return null; } List<Integer> res=new ArrayList<>(); int[] hash=new int[size]; for(int i=0;i<size;++i){ hash[arr[i]]++; if(hash[arr[i]]>1){ res.add(arr[i]); } } return res; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<int> duplicateNum(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (arr.empty() || size == 0) 10 return vector<int>(); 11 vector<int> hash(size); 12 vector<int> res; 13 for (int i = 0; i < size; ++i) 14 { 15 hash[arr[i]]++; 16 if (hash[arr[i]] > 1) 17 res.push_back(arr[i]); 18 } 19 return res; 20 } 21 22 int main() 23 { 24 vector<int> arr = { 2,3,1,0,2,5,3 }; 25 vector<int> res = duplicateNum(arr); 26 for (int i = 0; i < res.size(); ++i) 27 cout << res[i] << " "; 28 cout << endl; 29 30 return 0; 31 }
24、反转双链表
Java实现:

package com.mian.algorithm; import java.util.Scanner; public class ReverseDoubleList { public static void main(String[] args) { ReverseDoubleList rdl=new ReverseDoubleList(); DoubleListNode head=rdl.createDoubleList(); rdl.printDoubleList(head); System.out.println("------------------"); DoubleListNode last= rdl.reverseDoubleList(head); rdl.printDoubleList(last); } private DoubleListNode createDoubleList(){ int val; DoubleListNode head=null; DoubleListNode cur=null; DoubleListNode pre=null; System.out.println("enter list value (enter 100 to quit):"); Scanner sc=new Scanner(System.in); val=sc.nextInt(); while(val!=100){ cur=new DoubleListNode(val); if(head==null){ head=cur; } if(pre==null) { cur.last=null; cur.next=null; }else{ cur.last=pre; pre.next=cur; } pre=cur; System.out.println("enter list value (enter 100 to quit):"); val=sc.nextInt(); } return head; } private DoubleListNode reverseDoubleList(DoubleListNode head){ if(head==null){ return head; } DoubleListNode pre=null; DoubleListNode next=null; while(head!=null){ next=head.next; head.next=pre; head.last=next; pre=head; head=next; } return pre; } private void printDoubleList(DoubleListNode head){ if(head==null){ return; } DoubleListNode cur=head; while(cur.next!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(cur.val); while(cur!=null){ System.out.print(cur.val+" "); cur=cur.last; } System.out.println(); } } class DoubleListNode{ public int val; DoubleListNode next; DoubleListNode last; DoubleListNode(){} DoubleListNode(int v){ this.val=v; this.next=null; this.last=null; } }
C++实现:

1 class DoubleListNode { 2 public: 3 int val; 4 DoubleListNode *next; 5 DoubleListNode *last; 6 DoubleListNode(int v):val(v),next(nullptr),last(nullptr){} 7 }; 8 9 DoubleListNode *reverseDoubleList(DoubleListNode *head) 10 { 11 if (head == nullptr) 12 return head; 13 DoubleListNode *pre = nullptr; 14 DoubleListNode *next = nullptr; 15 while (head) 16 { 17 next = head->next; 18 head->next = pre; 19 head->last = next; 20 pre = head; 21 head = next; 22 } 23 return pre; 24 }
25、字符串转整数
Java实现:

package com.mian.algorithm; public class MyAtoi { public static void main(String[] args){ } private int myAtoi(String str){ str = str.trim(); if(str.isEmpty()){ return 0; } boolean isPositive = true; long num = 0; int i = 0; char firstChar = str.charAt(0); if(Character.isDigit(firstChar)) { i = 0; isPositive = true; }else if (firstChar == '+') { i = 1; isPositive = true; }else if (firstChar == '-'){ i = 1; isPositive = false; } char c; for(; i < str.length(); i++) { c = str.charAt(i); if(Character.isDigit(c) && num < Integer.MAX_VALUE){ num = num * 10 + (c - '0'); } else{ break; } } if(!isPositive) { num*=-1; } if(num < Integer.MIN_VALUE){ return Integer.MIN_VALUE; }else if(num > Integer.MAX_VALUE){ return Integer.MAX_VALUE; }else{ return (int)num; } } }
C++实现:

1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 int myAtoi(string &str) 7 { 8 if (str.empty()) 9 return 0; 10 int sign = 1, base = 0, i = 0, n = str.size(); 11 while (i < n&&str[i] == ' ') 12 ++i; 13 if (str[i] == '+' || str[i] == '-') 14 sign = (str[i++] == '+') ? 1 : -1; 15 while (i < n&&str[i] >= '0'&&str[i] <= '9') 16 { 17 if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) 18 return (sign == 1) ? INT_MAX : INT_MIN; 19 base = 10 * base + (str[i++] - '0'); 20 } 21 return base*sign; 22 } 23 24 int main() 25 { 26 string str = "-98384"; 27 cout << myAtoi(str) << endl; 28 29 return 0; 30 }
26、字符串转换float
Java实现:

package com.mian.algorithm; public class StringToFloat { public static void main(String[] args) { StringToFloat stf=new StringToFloat(); float res=stf.stringToFloat("89.432"); System.out.println(res); } private float stringToFloat(String str){ int size=str.length(); if(str.isEmpty()||size==0){ return Float.MIN_VALUE; } float res=0; int sign=1; if(str.charAt(0)=='+'){ sign=1; }else if(str.charAt(0)=='-'){ sign=-1; }else if(str.charAt(0)>='0'&&str.charAt(0)<='9'){ res+=str.charAt(0)-'0'; }else{ return Float.MIN_VALUE; } int index=str.indexOf('.'); for(int i=1;i<index;++i){ if(str.charAt(i)<'0'||str.charAt(i)>'9'){ return Float.MIN_VALUE; } res=res*10+(str.charAt(i)-'0'); } float total=0; for(int i=index+1;i<size;++i){ if(str.charAt(i)<'0'||str.charAt(i)>'9'){ return Float.MIN_VALUE; } total=total*10+(str.charAt(i)-'0'); } int pos=1; for(int i=0;i<(size-index-1);++i){ pos*=10; } total=total/pos; return sign==1?(res+total):-(res+total); } }
C++实现:

1 #include<iostream> 2 #include<string> 3 4 using namespace std; 5 6 float str2float(string &str) 7 { 8 int size = str.size(); 9 if (str.empty() || size == 0) 10 return FLT_MIN; 11 float sum = 0; 12 int sign = 1; 13 if (str[0] == '+') 14 sign = 1; 15 else if (str[0] == '-') 16 sign = -1; 17 else if (str[0] >= '0'&&str[0] <= '9') 18 sum = str[0] - '0'; 19 else 20 return FLT_MIN; 21 size_t pos = str.find('.'); 22 cout << pos << endl; 23 for (int i = 1; i < pos; ++i) 24 { 25 if (str[i]<'0' || str[i]>'9') 26 return FLT_MIN; 27 sum = sum * 10 + str[i] - '0'; 28 } 29 float total = 0; 30 for (int i = pos + 1; i < size; ++i) 31 { 32 if (str[i]<'0' || str[i]>'9') 33 return FLT_MIN; 34 total = total * 10 + str[i] - '0'; 35 } 36 total = total / (pow(10,(size-pos-1))); 37 return sign == 1 ? (sum + total) : -(sum + total); 38 } 39 40 int main() 41 { 42 string str = "89.432"; 43 cout << str2float(str) << endl; 44 45 return 0; 46 }
27、字符串数组的字符串是否都能首尾相接
Java实现:

package com.mian.algorithm; import java.util.Arrays; public class StrOrgEnd { public static void main(String[] args){ String [] str = {"gj","jl","dg","ad","gg"}; StrOrgEnd sre=new StrOrgEnd(); sre.strOrgEnd(str,0); sre.strOrgEnd2(str,0); } private void strOrgEnd(String[] str,int k){ if(k==str.length){ System.out.println(Arrays.toString(str)); return; } for(int i=k;i<str.length;++i){ /** * 交换k+1和i * k=0,表明为第一个字符串,必须和自己以及后面每一个交换 * k>0时,假设0-(k-1)是排序好的,我们需比较k-1和i的顺序 */ if((k>0&&judge(str[k-1],str[i]))||k==0){ swap(str,k,i); strOrgEnd(str,k+1); swap(str,k,i); } } } private void strOrgEnd2(String[] str,int k){ if(k==str.length){ System.out.println(Arrays.toString(str)); return; } for(int i=k;i<str.length;++i){ if(k>0&&judge(str[k-1],str[i])){ swap(str,k,i); strOrgEnd(str,k+1); swap(str,k,i); }else if(k==0){ swap(str,k,i); strOrgEnd(str,k+1); swap(str,k,i); } } } private boolean judge(String str1,String str2){ if(str1.charAt(str1.length()-1)==str2.charAt(0)){ return true; } return false; } private void swap(String[] str,int i,int j){ String tmp=str[i]; str[i]=str[j]; str[j]=tmp; } }
C++实现:

1 #include<iostream> 2 #include<string> 3 #include<vector> 4 5 using namespace std; 6 7 void swap(vector<string> &arr, int i, int j) 8 { 9 string tmp = arr[i]; 10 arr[i] = arr[j]; 11 arr[j] = tmp; 12 } 13 14 bool judge(string &s1, string &s2) 15 { 16 if (s1[s1.size() - 1] == s2[0]) 17 return true; 18 return false; 19 } 20 21 void fun(vector<string> &arr, int k) 22 { 23 int size = arr.size(); 24 if (k == size) 25 { 26 for (int i = 0; i < size; ++i) 27 cout << arr[i] << " "; 28 cout << endl; 29 } 30 for (int i = k; i < size; ++i) 31 { 32 // k>0时,之前的0-k-1个字符串已经排好序,则判断k-1号字符串与之后的字符串 33 if (k > 0 && judge(arr[k - 1], arr[i])) 34 { 35 swap(arr, k, i); 36 fun(arr, k + 1); 37 swap(arr, k, i); 38 } 39 else if (k == 0)// k=0,表明为第一个字符串,必须和自己以及后面每一个交换并作出判断 40 { 41 swap(arr, k, i); 42 fun(arr, k + 1); 43 swap(arr, k, i); 44 } 45 } 46 } 47 48 int main() 49 { 50 vector<string> arr = { "gj", "jl", "dg", "ad", "gg" }; 51 fun(arr, 0); 52 53 return 0; 54 }
28、递归求和
Java实现:

package com.mian.algorithm; public class SumWithRecur { public static void main(String[] args){ SumWithRecur sw=new SumWithRecur(); int sum=sw.sumWithRecur(5); System.out.println(sum); } private int sumWithRecur(int n){ if(n==1){ return 1; } return sumWithRecur(n-1)+n; } }
C++实现:

1 #include<iostream> 2 3 using namespace std; 4 5 int sumWithRecur(int n) 6 { 7 if (n == 1) 8 return 1; 9 return sumWithRecur(n - 1) + n; 10 } 11 12 int main() 13 { 14 cout << sumWithRecur(5); 15 16 return 0; 17 }
29、交替打印数组
已知一个数组a1,a2,... an,b1,b2,...,bn,设计一个算法把数组变成a1,b1,a2,b2,...,an,bn。
Java实现:

package com.mian.algorithm; public class SwapPrintArray { public static void main(String[] args) { int a[]={ 1, 3, 4, 7, 9, 0 }; int b[]={ 21, 23, 25, 27, 29 }; int[] res=swapPrintArray(a,b); for(int i=0;i<res.length;++i){ System.out.print(res[i]+" "); } } private static int[] swapPrintArray(int[] a,int[] b){ int asize=a.length; int bsize=b.length; if(a==null&&b==null){ return a; } if(asize==0||a==null){ return b; } if(bsize==0||b==null){ return a; } int[] res=new int[asize+bsize]; int i=0; int j=0; int k=0; while(i<asize&&j<bsize){ if(i==j){ res[k++]=a[i++]; }else if(i>j){ res[k++]=b[j++]; } } while(i<asize){ res[k++]=a[i++]; } while(j<bsize){ res[k++]=b[j++]; } return res; } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 vector<int> swapPrintArray(vector<int> &a, vector<int> &b) 7 { 8 if (a.empty()&&b.empty()) 9 return vector<int>(); 10 if (a.empty()) 11 return b; 12 if (b.empty()) 13 return a; 14 vector<int> res(a.size() + b.size()); 15 int i = 0; 16 int j = 0; 17 int k = 0; 18 while (i < a.size() && j < b.size()) 19 { 20 if (i == j) 21 res[k++] = a[i++]; 22 else if (i > j) 23 res[k++] = b[j++]; 24 } 25 while (i < a.size()) 26 res[k++] = a[i++]; 27 while (j < b.size()) 28 res[k++] = b[j++]; 29 return res; 30 } 31 32 int main() 33 { 34 vector<int> tt = { 1, 3, 4, 7, 9, 0 }; 35 vector<int> rrr = { 21, 23, 25, 27, 29 }; 36 vector<int> res = swapPrintArray(tt, rrr); 37 for (int i = 0; i < res.size(); ++i) 38 cout << res[i] << " "; 39 cout << endl; 40 41 return 0; 42 }
30、输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S。
如果有多对数字的和等于S,输出两个数的乘积最小的。
Java实现:

package com.mian.algorithm; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TwoSum { public static void main(String[] args){ TwoSum twoSum=new TwoSum(); int[] arr={ 3, 5, 8, 9, 12, 16, 20, 23, 29, 30, 35 }; int target=38; //方法一 List<List<Integer>> res=twoSum.twoSumMap(arr,target); for(int i=0;i<res.size();++i){ for(int j=0;j<res.get(i).size();++j){ System.out.print(res.get(i).get(j)+" "); } System.out.println(); } //方法二 twoSum.twoSum(arr,target); //方法三 twoSum.twoSumFor(arr,target); } private List<List<Integer>> twoSumMap(int[] arr,int target){ List<List<Integer>> res=new ArrayList<>(); int size=arr.length; if(size==0||arr==null){ return res; } Map<Integer,Integer> map=new HashMap<>(); List<Integer> tmp=null; for(int i=0;i<size;++i){ if(map.containsKey(target-arr[i])){ tmp=new ArrayList<>(); tmp.add(arr[i]); tmp.add((target-arr[i])); res.add(tmp); } map.put(arr[i],arr[i]); } return res; } private void twoSum(int[] arr,int target){ int size=arr.length; if(size==0||arr==null){ return; } int i=0; int j=size-1; while(i<j){ if(arr[i]+arr[j]==target){ System.out.println(arr[i]+" "+arr[j]); ++i; --j; }else if(arr[i]+arr[j]>target){ --j; }else{ ++i; } } } private void twoSumFor(int[] arr,int target){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=0;i<size;++i){ for(int j=i;j<size;++j){ if(arr[j]==(target-arr[i])){ System.out.println(arr[i]+" "+arr[j]); } } } } }
C++实现:

1 #include<iostream> 2 #include<vector> 3 #include<unordered_map> 4 5 using namespace std; 6 7 //方法一 8 vector<vector<int>> twoSumMap(vector<int> &arr, int target) 9 { 10 vector<vector<int>> res; 11 int size = arr.size(); 12 if (arr.empty() || size == 0) 13 return res; 14 unordered_map<int, int> m; 15 for (int i = 0; i < size; ++i) 16 { 17 auto it = m.find(target - arr[i]); 18 if (it != m.end()) 19 { 20 vector<int> tmp; 21 tmp.push_back(arr[i]); 22 tmp.push_back(target - arr[i]); 23 res.push_back(tmp); 24 tmp.clear(); 25 } 26 m[arr[i]] = arr[i]; 27 } 28 return res; 29 } 30 31 //方法二 32 void twoSum(vector<int> &arr, int target) 33 { 34 int size = arr.size(); 35 if (arr.empty() || size == 0) 36 return; 37 int i = 0; 38 int j = size - 1; 39 while (i < j) 40 { 41 if (arr[i] + arr[j] == target) 42 { 43 cout << arr[i] << " " << arr[j] << endl; 44 ++i; 45 --j; 46 } 47 else if (arr[i] + arr[j] > target) 48 --j; 49 else 50 ++i; 51 } 52 } 53 //方法三 54 void twoSum2(vector<int> &arr, int target) 55 { 56 int size = arr.size(); 57 if (arr.empty() || size == 0) 58 return; 59 for (int i = 0; i < size; ++i) 60 for (int j = i; j < size; ++j) 61 if (arr[j] == target - arr[i]) 62 cout << arr[i] << " " << arr[j] << endl; 63 } 64 65 int main() 66 { 67 vector<int> tet = { 3, 5, 8, 9, 12, 16, 20, 23, 29, 30, 35 }; 68 vector<vector<int>> vr = twoSumMap(tet, 38); 69 for (int i = 0; i < vr.size(); ++i) 70 { 71 for (int j = 0; j < vr[i].size(); ++j) 72 cout << vr[i][j] << " "; 73 cout << endl; 74 } 75 76 twoSum(tet, 38); 77 twoSum2(tet, 38); 78 }