1、递归算法判断一个数组是否是递增数组
Java实现:
package com.mian.algorithm; public class ArrayIsIncrement { public static void main(String[] args) { ArrayIsIncrement arrayIsIncrement=new ArrayIsIncrement(); int[] arr={1,2,3,4,5,6,7}; int[] ar={0,9,4,1,2,}; System.out.println(arrayIsIncrement.arrayIsIncrement(arr,arr.length)); System.out.println(arrayIsIncrement.arrayIsIncrement(ar,ar.length)); } private boolean arrayIsIncrement(int[] arr,int size){ if(size==1){ return true; } return arr[size-1]>=arr[size-2]&&arrayIsIncrement(arr,size-1); } }
C++实现:
1 bool arrayIsIncrement(vector<int> &arr, int size) 2 { 3 if (size == 1) 4 return true; 5 return arr[size - 1] >= arr[size - 2] && arrayIsIncrement(arr, size - 1); 6 }
2、二分查找的递归与非递归实现
二分查找的时间复杂度是O(logn)
(1)递归实现
Java实现:
package com.mian.algorithm; import com.sun.org.apache.bcel.internal.generic.BIPUSH; public class BinarySearchRecur { public static void main(String[] args) { int arr[]={1,2,3,5,7,9,11}; int target=7; BinarySearchRecur bs=new BinarySearchRecur(); int index=bs.binarySearchRecur(arr,0,arr.length-1,target); System.out.println(index); } private int binarySearchRecur(int[] arr,int start,int end,int target){ if(start>end){ return -1; } int mid=(start+end)>>1; if(arr[mid]==target){ return mid; }else if(arr[mid]>target){ return binarySearchRecur(arr,start,mid-1,target); }else{ return binarySearchRecur(arr,mid+1,end,target); } } }
C++实现:
1 int binarySearchRecur(vector<int> &arr, int target) 2 { 3 int size = arr.size(); 4 if (size == 0 || arr.empty()) 5 return -1; 6 return binarySearchRecursion(arr, 0, size - 1, target); 7 } 8 9 int binarySearchRecursion(vector<int> &arr, int start, int end, int target) 10 { 11 if (start > end) 12 return -1; 13 int mid = (start + end) / 2; 14 if (arr[mid] == target) 15 return mid; 16 else if (arr[mid] > target) 17 return binarySearchRecursion(arr, start, mid - 1, target); 18 else 19 return binarySearchRecursion(arr, mid + 1, end, target); 20 }
(2)非递归实现
Java实现:
package com.mian.algorithm; public class BinarySearch { public static void main(String[] args) { int arr[]={1,2,3,5,7,9,11}; int target=7; BinarySearch bs=new BinarySearch(); int index=bs.binarySearch(arr,target); System.out.println(index); } private int binarySearch(int[] arr,int target){ int size=arr.length; if(size==0||arr==null){ return -1; } int start=0; int end=size-1; int mid=0; while(start<=end){ mid=(start+end)>>1; if(arr[mid]>target){ end=mid-1; }else if(arr[mid]<target){ start=mid+1; }else{ while(mid-1>=0){ if(arr[mid-1]==target){ --mid; }else{ break; } } return mid; } } return -1; } }
C++实现:
1 int binarySearch(vector<int> &arr, int target) 2 { 3 int size = arr.size(); 4 if (size == 0 || arr.empty()) 5 return -1; 6 int start = 0; 7 int end = size - 1; 8 int mid = 0; 9 while (start <= end) 10 { 11 mid = (start + end) / 2; 12 if (arr[mid] > target) 13 end = mid - 1; 14 else if (arr[mid] < target) 15 start = mid + 1; 16 else 17 { 18 //元素重复则返回第一个元素的索引 19 while (mid - 1 >= 0) 20 if (arr[mid - 1] == target) 21 --mid; 22 else 23 break; 24 return mid; 25 } 26 } 27 return -1; 28 }
3、正整数序列Q中的每个元素都至少能被正整数a和b中的一个整除,现给定a和b,如何计算出Q中的前N项?
例如,当 a=3,b=5,N=6时,序列为3,5,6,9,10,12。
分析:可以和归并排序联系起来,给定两个数组 A、B,数组 A 存放:3 x 1,3 x 2,3 x 3,…
数组 B 存放 5 x 1,5 x 2,5 x 3,… 有两个指针 i、j,分别指向 A、B 的第一个元素,取 Min(A[ i ], B[ j ]),
并将较小值的指针前移,然后继续比较(即归并排序中的“合并两个有序序列“)。
当然,实现时没有必要申请两个数组,用两个变量即可
Java实现:
package com.mian.algorithm; public class CreateArray { public static void main(String[] args) { CreateArray createArray=new CreateArray(); int[] res=createArray.createArray(3,5,6); for(int i=0;i<res.length;++i){ System.out.print(res[i]+" "); } } private int[] createArray(int a,int b,int n){ int[] res=new int[n]; if(n<=0){ return null; } int i=1,j=1; int k=0; while(k<n){ if(i*a<j*b){ res[k++]=i*a; ++i; }else{ res[k++]=j*b; ++j; } } return res; } }
C++实现:
1 vector<int> createArray(int a, int b, int n) 2 { 3 vector<int> res(n); 4 if (n <= 0) 5 return res; 6 int i = 1, j = 1; 7 int k = 0; 8 while (k < n) 9 { 10 if (i*a < j*b) 11 { 12 res[k++] = i*a; 13 ++i; 14 } 15 else 16 { 17 res[k++] = j*b; 18 ++j; 19 } 20 } 21 return res; 22 }
4、删除数组中重复的元素
Java实现:
package com.mian.algorithm; import java.util.ArrayList; import java.util.List; public class DeleteRepeateEle { public static void main(String[] args) { DeleteRepeateEle dre=new DeleteRepeateEle(); int[] arr={1,3,5,2,3,5,6,2}; List<Integer> res=dre.deleteRepeateEle(arr); for(int i=0;i<res.size();++i){ System.out.print(res.get(i)+" "); } } private List<Integer> deleteRepeateEle(int[] arr){ List<Integer> res=new ArrayList<>(); int size=arr.length; if(size<=1||arr==null){ return res; } int min=Integer.MAX_VALUE; int max=Integer.MIN_VALUE; for(int i=0;i<size;++i){ if(arr[i]<min){ min=arr[i]; } if(arr[i]>max){ max=arr[i]; } } int[] help=new int[max-min+1]; for(int i=0;i<size;++i){ ++help[arr[i]-min]; } for(int i=0;i<size;++i){ if(help[arr[i]-min]==1){ res.add(arr[i]); } } return res; } }
C++实现:
1 vector<int> deleteRepeateEle(vector<int> &arr) 2 { 3 vector<int> res; 4 int size = arr.size(); 5 if (size <= 1 || arr.empty()) 6 return res; 7 int min = INT_MAX; 8 int max = INT_MIN; 9 for (int i = 0; i < size; ++i) 10 { 11 if (arr[i] < min) 12 min = arr[i]; 13 if (arr[i] > max) 14 max = arr[i]; 15 } 16 vector<int> help(max - min + 1); 17 for (int i = 0; i < size; ++i) 18 ++help[arr[i] - min]; 19 for (int i = 0; i < size; ++i) 20 if (help[arr[i] - min] == 1) 21 res.push_back(arr[i]); 22 return res; 23 }
5、删除单链表中重复的结点
(1)递归实现,保留一个重复的结点元素
Java实现:
package com.mian.algorithm; import java.util.Scanner; public class DeleteRepeateNodeRecur { public static void main(String[] args) { DeleteRepeateNodeRecur drnr=new DeleteRepeateNodeRecur(); ListNode head=drnr.createList(); drnr.printListNode(head); ListNode singleHead=drnr.deleteRepeateNodeRecur(head); drnr.printListNode(singleHead); } private ListNode deleteRepeateNodeRecur(ListNode head){ if(head==null||(head!=null&&head.next==null)){ return head; } ListNode tmp=head; ListNode next=deleteRepeateNodeRecur(head.next); if(next!=null){ if(tmp.val==next.val){ tmp.next=next.next; } } return head; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printListNode(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode { 6 public: 7 int val; 8 ListNode* next; 9 ListNode(){} 10 ListNode(int x):val(x),next(nullptr){} 11 }; 12 13 void printListNode(ListNode* head) 14 { 15 ListNode* cur = head; 16 while (cur) 17 { 18 cout << cur->val << " "; 19 cur = cur->next; 20 } 21 cout << endl; 22 } 23 24 ListNode* createListNode() 25 { 26 int in; 27 ListNode* head = nullptr; 28 cout << "enter list val (enter 100 to quit):"; 29 cin >> in; 30 if (in == 100) 31 return head; 32 else 33 { 34 head = new ListNode(in); 35 head->next = createListNode(); 36 } 37 return head; 38 } 39 40 ListNode* deleteRepeateNode(ListNode* head) 41 { 42 if (head == nullptr) 43 return nullptr; 44 if (head != nullptr&&head->next == nullptr) 45 return head; 46 ListNode* tmp = head; 47 ListNode* next = deleteRepeateNode(head->next); 48 if (next) 49 if (tmp->val == next->val) 50 tmp->next = next->next; 51 return head; 52 } 53 54 int main() 55 { 56 ListNode* head = createListNode(); 57 printListNode(head); 58 printListNode(deleteRepeateNode(head)); 59 60 return 0; 61 }
(2)非递归实现,保留一个重复的结点元素
Java实现:
package com.mian.algorithm; import java.util.Scanner; public class DeleteRepeateNode { public static void main(String[] args) { DeleteRepeateNode drnr=new DeleteRepeateNode(); ListNode head=drnr.createList(); drnr.printListNode(head); ListNode singleHead=drnr.deleteRepeateNode(head); drnr.printListNode(singleHead); } private ListNode deleteRepeateNode(ListNode head){ if(head==null||(head!=null&&head.next==null)){ return head; } ListNode cur=head; while(cur!=null){ while(cur.next!=null&&cur.val==cur.next.val){ cur.next=cur.next.next; } cur=cur.next; } return head; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printListNode(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode { 6 public: 7 int val; 8 ListNode* next; 9 ListNode() {} 10 ListNode(int x) :val(x), next(nullptr) {} 11 }; 12 13 void printListNode(ListNode* head) 14 { 15 ListNode* cur = head; 16 while (cur) 17 { 18 cout << cur->val << " "; 19 cur = cur->next; 20 } 21 cout << endl; 22 } 23 24 ListNode* createListNode() 25 { 26 int in; 27 ListNode* head = nullptr; 28 cout << "enter list val (enter 100 to quit):"; 29 cin >> in; 30 if (in == 100) 31 return head; 32 else 33 { 34 head = new ListNode(in); 35 head->next = createListNode(); 36 } 37 return head; 38 } 39 40 ListNode* deleteRepeateNode(ListNode* head) 41 { 42 ListNode* cur = head; 43 while (cur) 44 { 45 while (cur->next&&cur->val == cur->next->val) 46 cur->next = cur->next->next; 47 cur = cur->next; 48 } 49 return head; 50 } 51 52 int main() 53 { 54 ListNode* head = createListNode(); 55 printListNode(head); 56 printListNode(deleteRepeateNode(head)); 57 58 return 0; 59 }
(3)递归实现,不保留重复结点元素
Java实现:
package com.mian.algorithm; import java.util.Scanner; public class DeleteRepeateRecur { public static void main(String[] args) { DeleteRepeateRecur dr=new DeleteRepeateRecur(); ListNode head=dr.createList(); dr.printListNode(head); ListNode singleHead=dr.deleteRepeateRecur(head); dr.printListNode(singleHead); } private ListNode deleteRepeateRecur(ListNode head){ if(head==null||(head!=null&&head.next==null)){ return head; } ListNode cur=null; if(head.val==head.next.val){ cur=head.next; while(cur!=null&&cur.val==head.val){ cur=cur.next; } return deleteRepeateRecur(cur); }else{ cur=head.next; head.next=deleteRepeateRecur(cur); return head; } } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printListNode(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode { 6 public: 7 int val; 8 ListNode* next; 9 ListNode() {} 10 ListNode(int x) :val(x), next(nullptr) {} 11 }; 12 13 void printListNode(ListNode* head) 14 { 15 ListNode* cur = head; 16 while (cur) 17 { 18 cout << cur->val << " "; 19 cur = cur->next; 20 } 21 cout << endl; 22 } 23 24 ListNode* createListNode() 25 { 26 int in; 27 ListNode* head = nullptr; 28 cout << "enter list val (enter 100 to quit):"; 29 cin >> in; 30 if (in == 100) 31 return head; 32 else 33 { 34 head = new ListNode(in); 35 head->next = createListNode(); 36 } 37 return head; 38 } 39 40 ListNode* deleteRepeateNode(ListNode* head) 41 { 42 if (!head || head && !head->next) 43 return head; 44 ListNode* cur = nullptr; 45 if (head->val == head->next->val) 46 { 47 cur = head->next; 48 while (cur&&cur->val == head->val) 49 cur = cur->next; 50 return deleteRepeateNode(cur); 51 } 52 else 53 { 54 cur = head->next; 55 head->next = deleteRepeateNode(cur); 56 return head; 57 } 58 } 59 60 int main() 61 { 62 ListNode* head = createListNode(); 63 printListNode(head); 64 printListNode(deleteRepeateNode(head)); 65 66 return 0; 67 }
(4)非递归实现,不保留重复结点元素
Java实现:
package com.mian.algorithm; import java.util.Scanner; public class DeleteRepeate{ public static void main(String[] args) { DeleteRepeate dr=new DeleteRepeate(); ListNode head=dr.createList(); dr.printListNode(head); ListNode singleHead=dr.deleteRepeate(head); dr.printListNode(singleHead); } private ListNode deleteRepeate(ListNode head){ if(head==null||(head!=null&&head.next==null)){ return head; } ListNode first=new ListNode(-1); first.next=head; ListNode p=head; ListNode last=first; while (p!=null&&p.next!=null){ if(p.val==p.next.val){ int val=p.val; while(p!=null&&p.val==val){ p=p.next; } last.next=p; }else { last=p; p=p.next; } } return first.next; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printListNode(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode { 6 public: 7 int val; 8 ListNode* next; 9 ListNode() {} 10 ListNode(int x) :val(x), next(nullptr) {} 11 }; 12 13 void printListNode(ListNode* head) 14 { 15 ListNode* cur = head; 16 while (cur) 17 { 18 cout << cur->val << " "; 19 cur = cur->next; 20 } 21 cout << endl; 22 } 23 24 ListNode* createListNode() 25 { 26 int in; 27 ListNode* head = nullptr; 28 cout << "enter list val (enter 100 to quit):"; 29 cin >> in; 30 if (in == 100) 31 return head; 32 else 33 { 34 head = new ListNode(in); 35 head->next = createListNode(); 36 } 37 return head; 38 } 39 40 ListNode* deleteRepeateNode(ListNode* head) 41 { 42 ListNode* first = new ListNode(-1); 43 first->next = head; 44 ListNode* p = head; 45 ListNode* last = first; 46 while (p&&p->next) 47 { 48 if (p->val == p->next->val) 49 { 50 int val = p->val; 51 while (p&&p->val == val) 52 p = p->next; 53 last->next = p; 54 } 55 else 56 { 57 last = p; 58 p = p->next; 59 } 60 } 61 return first->next; 62 } 63 64 int main() 65 { 66 ListNode* head = createListNode(); 67 printListNode(head); 68 printListNode(deleteRepeateNode(head)); 69 70 return 0; 71 }
6、浮点数的平方根
(1)暴力搜索
Java实现:
package com.mian.algorithm; public class MySqrt{ public static void main(String[] args) { MySqrt mySqrt=new MySqrt(); int s=mySqrt.mySqrt(9); System.out.println(s); } private int mySqrt(int x){ if(x<=0){ return x; } int begin=1; int end=x; int mid=0; while(begin<=end){ mid=(begin+end)>>1; if(mid==x/mid){ return mid; }else if(mid<x/mid){ begin=mid+1; }else{ end=mid-1; } } return end;//结束条件end一定<begin,所以返回end } }
C++实现:
1 int mySqrt(int x) 2 { 3 if(x<=0) 4 return x; 5 int begin=1; 6 int end=x; 7 int mid=0; 8 while(begin<=end) 9 { 10 mid=(begin+end)/2; 11 if(mid==x/mid) 12 return mid; 13 else if(mid<x/mid) 14 begin=mid+1; 15 else 16 end=mid-1; 17 } 18 return end;//结束条件end一定<begin,所以返回end 19 }
(2)牛顿迭代法
Java实现:
package com.mian.algorithm; public class MySqrt{ public static void main(String[] args) { MySqrt mySqrt=new MySqrt(); int s=mySqrt.mySqrt(9); System.out.println(s); } private int mySqrt(int x){ long v=x; while(v*v>x){ v=(v+x/v)>>1; } return (int)v; } }
C++实现:
1 int mySqrt(int x) 2 { 3 long long v=x; 4 while(v*v>x) 5 v=(v+x/v)>>1; 6 return v; 7 }
7、交换单链表中任意两个结点
Java实现:
package com.mian.algorithm; import java.util.List; import java.util.Scanner; public class ExchangeTwoNode { public static void main(String[] args) { ExchangeTwoNode et=new ExchangeTwoNode(); ListNode head=et.createList(); et.printList(head); ListNode node1=head.next.next; ListNode node2=head.next.next.next.next.next; ListNode node=et.exchangeTwoNode(head,node1,node2); et.printList(node); } private ListNode exchangeTwoNode(ListNode head,ListNode node1,ListNode node2){ if(head==null||node1==null||node2==null){ return head; } if(node1.val==node2.val){ return head; } if(node1.next==node2){ ListNode pre=findPreNode(head,node1); pre.next=node2; node1.next=node2.next; node2.next=node1; }else if(node2.next==node1){ ListNode pre=findPreNode(head,node2); pre.next=node1; node2.next=node1.next; node1.next=node2; }else if(node1!=node2){ ListNode pre1=findPreNode(head,node1); ListNode pre2=findPreNode(head,node2); ListNode tmp=node1.next; node1.next=node2.next; node2.next=tmp; pre1.next=node2; pre2.next=node1; } return head; } 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; } ListNode findPreNode(ListNode head,ListNode node){ if(head==null||node==null){ return null; } ListNode p=head; while(p!=null){ if(p.next==node){ return p; }else{ p=p.next; } } return null; } private void printList(ListNode head){ ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 class ListNode { 6 public: 7 int val; 8 ListNode* next; 9 ListNode() {} 10 ListNode(int x) :val(x), next(nullptr) {} 11 }; 12 13 void printListNode(ListNode* head) 14 { 15 ListNode* cur = head; 16 while (cur) 17 { 18 cout << cur->val << " "; 19 cur = cur->next; 20 } 21 cout << endl; 22 } 23 24 ListNode* findPreNode(ListNode* head, ListNode* node) 25 { 26 if (head == nullptr || node == nullptr) 27 return nullptr; 28 ListNode* p = head; 29 while (p) 30 if (p->next == node) 31 return p; 32 else 33 p = p->next; 34 return nullptr; 35 } 36 37 ListNode* exchangeTwoNode(ListNode* head, ListNode* node1, ListNode* node2) 38 { 39 if (head == nullptr || node1 == nullptr || node2 == nullptr) 40 return head; 41 if (node1->val == node2->val) 42 return head; 43 if (node1->next == node2) 44 { 45 ListNode* pre = findPreNode(head, node1); 46 pre->next = node2; 47 node1->next = node2->next; 48 node2->next = node1; 49 } 50 else if (node2->next == node1) 51 { 52 ListNode* pre = findPreNode(head, node2); 53 pre->next = node1; 54 node2->next = node1->next; 55 node1->next = node2; 56 } 57 else if (node1 != node2) 58 { 59 ListNode* pre1 = findPreNode(head, node1); 60 ListNode* pre2 = findPreNode(head, node2); 61 ListNode* tmp = node1->next; 62 node1->next = node2->next; 63 node2->next = tmp; 64 pre1->next = node2; 65 pre2->next = node1; 66 } 67 return head; 68 } 69 70 ListNode* createNode() 71 { 72 int in; 73 ListNode* head = nullptr; 74 cout << "enter list value (enter 100 to quit):"; 75 cin >> in; 76 if (in == 100) 77 return head; 78 else 79 { 80 head = new ListNode(in); 81 head->next = createNode(); 82 } 83 return head; 84 } 85 86 int main() 87 { 88 ListNode* head = createNode(); 89 ListNode* node1 = head->next; 90 ListNode* node2 = head->next->next->next->next; 91 printListNode(head); 92 printListNode(exchangeTwoNode(head, node1, node2)); 93 94 return 0; 95 }
8、如何判断一个整数 x 是否可以表示成 n(n >= 2)个连续正整数的和。
分析:假设 x 可以表示成 n(n >= 2)个连续正整数的和,那么x = m + (m + 1) + (m + 2) + … + (m + n - 1),其中 m 为分解成的连续整数中最小的那一个(且 m 是大于等于 1 的正整数),可推出 x = (2m + n - 1)*n/2,变换之后 m = (2*x/n - n + 1)/2;由 m 的取值范围可知 (2*x/n - n + 1)/2 >= 1,又因为 m 是正整数,所以(2*x/n - n + 1) 一定要为偶数;否则m = (2*x/n - n + 1)/2 就是小数,不符合要求;(注意:(2*x/n - n + 1) 看成是 float 类型的)。给定一个 n,看 x 是否能分解成 n 个连续整数的和,可以判断是否存在 m,也就是 (2*x/n - n + 1) 是否是偶数的问题。
Java实现:
package com.mian.algorithm; public class ContinuousSequence { public static void main(String[] args) { findContinuousSequence(32,5); } private static void findContinuousSequence(int x,int n){ float tmp=(float)2*x/n-(float)(n-1); int m=(int)tmp/2; if((int)tmp%2==0&&m>=1){ System.out.print("x可分解为: "); int start=m; int end=m+n-1; while(start<=end){ System.out.print(start+" "); ++start; } System.out.println(); }else{ System.out.println("x不可分解"); } } }
C++实现:
1 void findContinuousSequence(int x, int n) 2 { 3 float temp = (float)2 * x / n - (float)(n - 1); 4 int m = (int)temp / 2; 5 if ((int)temp % 2 == 0 && m >= 1) 6 { 7 cout << "x可分解为 : "; 8 int start = m; 9 int end = m + n - 1; 10 while (start <= end) 11 { 12 cout << start << " "; 13 start++; 14 } 15 cout << endl; 16 } 17 else 18 cout << "x不可分解" << endl; 19 }
9、给一个由n-1个数组成的未经排序的数列,其元素都是1—n中的不同的整数。找出缺失的整数?
Java实现:
package com.mian.algorithm; import java.io.FileOutputStream; public class FindLost { public static void main(String[] args) { FindLost findLost=new FindLost(); int arr[]={1,2,3,5,9,7,8,6}; findLost.findLost(arr); } private void findLost(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } int sum1=0; int sum2=0; for(int i=0;i<size;++i){ sum1+=arr[i]; sum2+=i; } sum2+=size; System.out.println((sum2-sum1+size+1)); } }
C++实现:
1 void findLost(vector<int> &arr) 2 { 3 int size = arr.size(); 4 if (arr.empty() || size == 0) 5 return; 6 int sum1 = 0; 7 int sum2 = 0; 8 for (int i = 0; i < size; ++i) 9 { 10 sum1 += arr[i]; 11 sum2 += i; 12 } 13 sum2 += size; 14 cout << (sum2 - sum1 + size + 1) << endl; 15 }
10、字符串中第一个出现一次的字符
Java实现:
package com.mian.algorithm; import java.util.HashMap; import java.util.Map; public class FindFirstCharWithMap { public static void main(String[] args) { FindFirstCharWithMap fcm=new FindFirstCharWithMap(); fcm.findFirstCharWithMap("afdazfexafd"); fcm.findFirstChar("afdazfexafd"); } private void findFirstChar(String str){ int size=str.length(); if(size==0||str.isEmpty()){ return; } int[] hash=new int[256]; for(int i=0;i<size;++i){ ++hash[str.charAt(i)]; } for(int i=0;i<size;++i){ if(hash[str.charAt(i)]==1){ System.out.println(str.charAt(i)); break; } } } private void findFirstCharWithMap(String str){ int size=str.length(); if(size==0||str.isEmpty()){ return; } Map<Character,Integer> map=new HashMap<>(); for(int i=0;i<size;++i){ if(map.containsKey(str.charAt(i))){ map.put(str.charAt(i),map.get(str.charAt(i))+1); }else{ map.put(str.charAt(i),1); } } for(int i=0;i<size;++i){ if(map.get(str.charAt(i))==1){ System.out.println(str.charAt(i)); break; } } } }
C++实现:
(1)unordered_map
1 void findFirstCharWithMap(string str) 2 { 3 int size = str.size(); 4 if (size == 0 || str.empty()) 5 return; 6 unordered_map<char, int> m; 7 for (int i = 0; i < size; ++i) 8 ++m[str[i]]; 9 for (int i = 0; i < size; ++i) 10 if (m[str[i]] == 1) 11 { 12 cout << str[i] << endl; 13 break; 14 } 15 }
(2)vector
1 void findFirstChar(string str) 2 { 3 int size = str.size(); 4 if (size == 0 || str.empty()) 5 return; 6 vector<int> hash(256,0); 7 for (int i = 0; i < size; ++i) 8 ++hash[str[i]]; 9 for (int i = 0; i < size; ++i) 10 if (hash[str[i]] == 1) 11 { 12 cout << str[i] << endl; 13 break; 14 } 15 }
11、求两个数组的交集
Java实现:
package com.mian.demo; import java.util.Arrays; public class IntersectArray { public static void main(String[] args) { IntersectArray intersectArray=new IntersectArray(); int[] arr1={9,4,3,0,2,7,6,8}; int[] arr2={5,2,8,1,0,3}; intersectArray.intersectArray(arr1,arr2); } private void intersectArray(int[] arr1,int[] arr2){ int size1=arr1.length; int size2=arr2.length; if(arr1==null||size1==0||arr2==null||size2==0){ return; } Arrays.sort(arr1); Arrays.sort(arr2); int i=0,j=0; while(i<size1&&j<size2){ if(arr1[i]==arr2[j]){ System.out.print(arr1[i]+" "); ++i; ++j; }else if(arr1[i]>arr2[j]){ ++j; }else{ ++i; } } System.out.println(); } }
C++实现:
1 void intersectArray(vector<int> &arr1, vector<int> &arr2) 2 { 3 int size1 = arr1.size(); 4 int size2 = arr2.size(); 5 if (arr1.empty() || arr2.empty() || size1 == 0 || size2 == 0) 6 return; 7 sort(arr1.begin(), arr1.end()); 8 sort(arr2.begin(),arr2.end()); 9 int i = 0, j = 0; 10 while (i < size1 && j < size2) { 11 if (arr1[i] == arr2[j]) { 12 cout << arr1[i] << " "; 13 ++i; 14 ++j; 15 } 16 else if (arr1[i] > arr2[j]) { 17 ++j; 18 } 19 else { 20 ++i; 21 } 22 } 23 cout << endl; 24 }
12、如何判断一个数组中的数值是否连续相邻
一个整数数组,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现;0是例外,可以反复出现。
设计一个算法,判断这个数组中的元素是否连续相邻。
需要注意以下4点:
(1)数值允许是乱序的,如 8 7 5 0 6。
(2)0可以通配任意数值,如8 7 5 0 6中的0可以通配成9或者4.
(3)0可以多次出现。
(4)全0算连续,只有一个非0算连续。
分析:如果没有0的存在,要组成连续的数列,最大值和最小值的差距必须是n-1;存在0的情况下,只要最大值可最小值的差距小于n-1就可以了,缺失的数值可以用0通配。所以找出数列中非0的最大值和非0的最小值,时间复杂度为O(n)。如果非0最大-非0最小+1<n,即非0最大-非0最小<=n-1,则这n个数值连续相邻。否则,不连续相邻。因此,总体复杂度为O(n)。
Java实现:
package com.mian.demo; public class IsContinues { public static void main(String[] args) { } private boolean isContinues(int[] arr){ int size=arr.length; if(arr==null||size==0){ return true; } int max=Integer.MIN_VALUE; int min=Integer.MAX_VALUE; for(int i=0;i<size;++i){ if(arr[i]!=0){ if(arr[i]>max){ max=arr[i]; } if(arr[i]<min){ min=arr[i]; } } } return (max-min)<=(size-1)?true:false; } }
C++实现:
1 bool isContinues(vector<int> &arr) 2 { 3 int size = arr.size(); 4 if (arr.empty() || size == 0) 5 return true; 6 int max = arr[0]; 7 int min = arr[0]; 8 for (int i = 0; i < size; ++i) 9 { 10 if (arr[i] != 0) 11 { 12 if (arr[i] > max) 13 max = arr[i]; 14 if (arr[i] < min) 15 min = arr[i]; 16 } 17 } 18 return (max - min) <= (size - 1) ? true : false; 19 }
13、删除单链表的节点
(1)删除的结点以值的形式给出,链表中结点的值不重复
Java实现:
package com.mian.demo; import java.util.List; import java.util.Scanner; public class DeleteListNode { public static void main(String[] args) { DeleteListNode deleteListNode=new DeleteListNode(); ListNode head=deleteListNode.createList(); deleteListNode.printList(head); deleteListNode.deleteListNode(head,7); deleteListNode.printList(head); } private void deleteListNode(ListNode head,int val){ if(head==null){ return; } ListNode p=head; ListNode last=head; if(head.val==val){ head.val=head.next.val; head.next=head.next.next; }else{ while(last.next!=null){ last=last.next; } if(last.val!=val){ while(p.next!=null){ if(p.next.val==val){ p.next=p.next.next; } p=p.next; } }else{ while(p.next.next!=null){ p=p.next; } p.next=null; } } } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
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* createList() 15 { 16 int in; 17 ListNode* head = nullptr; 18 cout << "enter list val (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 = createList(); 26 } 27 return head; 28 } 29 30 void printNode(ListNode* head) 31 { 32 ListNode* p = head; 33 while (p) 34 { 35 cout << p->val << " "; 36 p = p->next; 37 } 38 cout << endl; 39 } 40 41 void deleteListNode(ListNode* head, int val) 42 { 43 if (head == nullptr) 44 return; 45 ListNode* p = head; 46 ListNode* last = head; 47 if (head->val == val) 48 { 49 head->val = head->next->val; 50 head->next = head->next->next; 51 } 52 else 53 { 54 while (last->next) 55 last = last->next; 56 if (last->val != val) 57 { 58 while (p->next) 59 { 60 if (p->next->val == val) 61 p->next = p->next->next; 62 p = p->next; 63 } 64 } 65 else 66 { 67 while (p->next->next) 68 p = p->next; 69 p->next = nullptr; 70 } 71 } 72 } 73 74 75 int main() 76 { 77 ListNode* head=createList(); 78 printNode(head); 79 deleteListNode(head, 3); 80 printNode(head); 81 82 return 0; 83 }
(2)删除的结点以节点的形式给出
Java实现:
package com.mian.demo; import java.util.Scanner; public class DeleteNode { public static void main(String[] args){ DeleteNode deleteNode=new DeleteNode(); ListNode head=deleteNode.createList(); deleteNode.printList(head); //删除头结点 ListNode del=head; deleteNode.deleteListNode(head,del); deleteNode.printList(head); //删除尾结点 ListNode last=head; while(last.next!=null){ last=last.next; } deleteNode.deleteListNode(head,last); deleteNode.printList(head); //删除中间结点 ListNode mid=head.next.next.next; deleteNode.deleteListNode(head,mid); deleteNode.printList(head); } private void deleteListNode(ListNode head,ListNode node){ if(head==null||node==null){ return; } if(head==node){ head.val=head.next.val; head.next=head.next.next; }else if(node.next!=null){ ListNode p=node.next; node.val=p.val; node.next=p.next; }else{ ListNode p=head; while(p!=null){ if(p.next==node){ p.next=null; } p=p.next; } } } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 #include<iostream> 2 #include<unordered_map> 3 4 using namespace std; 5 6 class ListNode 7 { 8 public: 9 int val; 10 ListNode* next; 11 ListNode(){} 12 ListNode(int x):val(x),next(nullptr){} 13 }; 14 15 ListNode* createNode() 16 { 17 int in; 18 ListNode* head = nullptr; 19 cout << "enter list value (enter 100 to quit):"; 20 cin >> in; 21 if (in == 100) 22 return head; 23 else 24 { 25 head = new ListNode(in); 26 head->next = createNode(); 27 } 28 return head; 29 } 30 31 void printList(ListNode* head) 32 { 33 if (head == nullptr) 34 return; 35 ListNode* p = head; 36 while (p) 37 { 38 cout << p->val << " "; 39 p = p->next; 40 } 41 cout << endl; 42 } 43 44 void deleteListNode(ListNode* head,ListNode* node) 45 { 46 if (head == nullptr || node == nullptr) 47 return; 48 if (head == node) 49 { 50 head->val = head->next->val; 51 head->next = head->next->next; 52 } 53 else if (node->next) 54 { 55 ListNode* p = node->next; 56 node->val = p->val; 57 node->next = p->next; 58 } 59 else 60 { 61 ListNode* p = head; 62 while (p) 63 { 64 if (p->next == node) 65 p->next = nullptr; 66 p = p->next; 67 } 68 } 69 } 70 71 int main() 72 { 73 ListNode* head = createNode(); 74 printList(head); 75 //删除头结点 76 ListNode* del = head; 77 deleteListNode(head, del); 78 printList(head); 79 //删除尾结点 80 ListNode* last = head; 81 while (last->next) 82 last = last->next; 83 deleteListNode(head, last); 84 printList(head); 85 //删除中间结点 86 ListNode* mid = head->next->next->next; 87 deleteListNode(head, mid); 88 printList(head); 89 90 return 0; 91 }
14、单链表中插入节点
分三种情况:插入到链表首部、中间、尾部
Java实现:
package com.mian.demo; import java.util.List; import java.util.Scanner; public class InsertNode { public static void main(String[] args){ InsertNode insertNode=new InsertNode(); ListNode head=insertNode.createList(); insertNode.printList(head); insertNode.insertNode(head,3,5); insertNode.printList(head); } private void insertNode(ListNode head,int val,int pos){ ListNode node=new ListNode(val); ListNode p=head; ListNode last=head; if(pos==0){ node.val=head.val; head.val=val; node.next=head.next; head.next=node; }else{ int index=1; while(p!=null&&index<pos){ ++index; p=p.next; } if(p!=null){ node.next=p.next; p.next=node; }else{ while(last.next!=null){ last=last.next; } last.next=node; } } } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter list val (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
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* createList() 15 { 16 int in; 17 ListNode* head = nullptr; 18 cout << "enter list val (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 = createList(); 26 } 27 return head; 28 } 29 30 void printNode(ListNode* head) 31 { 32 ListNode* p = head; 33 while (p) 34 { 35 cout << p->val << " "; 36 p = p->next; 37 } 38 cout << endl; 39 } 40 41 void insertNode(ListNode *head, int val, int pos) 42 { 43 ListNode* node= new ListNode(val); 44 ListNode* p = head; 45 ListNode* last = head; 46 if (pos == 0) 47 { 48 node->val = head->val; 49 head->val = val; 50 node->next = head->next; 51 head->next = node; 52 } 53 else 54 { 55 int index = 1; 56 while (p&&index < pos) 57 { 58 ++index; 59 p = p->next; 60 } 61 if (p) 62 { 63 node->next = p->next; 64 p->next = node; 65 } 66 else 67 { 68 while (last->next) 69 last = last->next; 70 last->next = node; 71 } 72 } 73 } 74 75 76 int main() 77 { 78 ListNode* head=createList(); 79 printNode(head); 80 insertNode(head, 3, 5); 81 printNode(head); 82 83 return 0; 84 }
15、判断两个链表是否交叉
单链表相交是指两个链表存在完全相同的部分(不是相交与一个结点)
判断单链表相交有两种方法:
方法一:将两个链表的首尾相连,监测是否有环
Java实现:
package com.mian.demo; import java.util.Scanner; public class GetLoopNode { public static void main(String[] args) { GetLoopNode gn=new GetLoopNode(); ListNode head=gn.createList(); ListNode mid=head.next.next.next; ListNode node=gn.createList(); gn.printList(node); ListNode last=node; while(last.next!=null){ last=last.next; } last.next=mid; gn.printList(head); gn.printList(node); ListNode loopNode=gn.getLoop(head,node); System.out.println(loopNode.val); } private ListNode getLoop(ListNode f,ListNode s){ if(f==null||s==null){ return null; } ListNode last=f; while(last.next!=null){ last=last.next; } last.next=s; return getLoopNode(f); } private ListNode getLoopNode(ListNode head){ if(head==null||head.next==null){ return head; } 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 ListNode createList(){ int val; ListNode head=null; System.out.println("enter node value (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 ListNode *getLoopNode(ListNode *head) 2 { 3 if (head == nullptr || head->next == nullptr || head->next->next == nullptr) 4 return head; 5 ListNode *n1 = head->next; 6 ListNode *n2 = head->next->next; 7 while (n1 != n2) 8 { 9 if (n1->next == nullptr || n2->next->next == nullptr) 10 return nullptr; 11 n1 = n1->next; 12 n2 = n2->next->next; 13 } 14 n2 = head; 15 while (n1 != n2) 16 { 17 n1 = n1->next; 18 n2 = n2->next; 19 } 20 return n1; 21 } 22 ListNode *getLoop(ListNode *f, ListNode *s) 23 { 24 if (f == nullptr || s == nullptr) 25 return nullptr; 26 while (s->next) 27 s = s->next; 28 s->next = f; 29 return getLoopNode(s); 30 }
方法二:如两个单链表相交,那么从相交结点开始到链表结束都是相同的结点,必然是Y字形,判断两个链表的最后一个结点是否相同即可。
Java实现:
package com.mian.demo; import java.util.Scanner; public class GetNodeWithLoop { public static void main(String[] args) { GetNodeWithLoop gn=new GetNodeWithLoop(); ListNode head=gn.createList(); ListNode mid=head.next.next.next; ListNode node=gn.createList(); gn.printList(node); ListNode last=node; while(last.next!=null){ last=last.next; } last.next=mid; gn.printList(head); gn.printList(node); ListNode loopNode=gn.getLoop(head,node); System.out.println(loopNode.val); } private ListNode getLoop(ListNode f,ListNode s){ if(f==null||s==null){ return null; } int n=0; ListNode cur1=f; ListNode cur2=s; while(cur1.next!=null){ cur1=cur1.next; ++n; } while(cur2.next!=null){ cur2=cur2.next; --n; } if(cur1!=cur2){ return null; } cur1=n>0?f:s; cur2=cur1==f?s:f; n=Math.abs(n); while(n!=0){ --n; cur1=cur1.next; } while(cur1!=cur2){ cur1=cur1.next; cur2=cur2.next; } return cur1; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter node value (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
C++实现:
1 ListNode *getNode(ListNode *f, ListNode *s) 2 { 3 if (f == nullptr || s == nullptr) 4 return nullptr; 5 int n = 0; 6 ListNode *cur1 = f; 7 ListNode *cur2 = s; 8 while (cur1->next) 9 { 10 cur1 = cur1->next; 11 n++; 12 } 13 while (cur2->next) 14 { 15 cur2 = cur2->next; 16 n--; 17 } 18 if (cur1 != cur2) 19 return nullptr; 20 cur1 = n > 0 ? f : s; 21 cur2 = cur1 == f ? s : f; 22 n = abs(n); 23 while (n) 24 { 25 n--; 26 cur1 = cur1->next; 27 } 28 while (cur1 != cur2) 29 { 30 cur1 = cur1->next; 31 cur2 = cur2->next; 32 } 33 return cur1; 34 }
16、找出数组中重复数字最多的数
Java实现:
package com.mian.demo; public class MaxCount { public static void main(String[] args) { MaxCount maxCount=new MaxCount(); int[] arr={9,3,5,2,1,6,3,1,2,4,5,3}; int res=maxCount.maxCount(arr); System.out.println(res); } private int maxCount(int[] arr){ int size=arr.length; int max=Integer.MIN_VALUE; int min=Integer.MAX_VALUE; for(int i=0;i<size;++i){ if(max<arr[i]){ max=arr[i]; } if(min>arr[i]){ min=arr[i]; } } int[] help=new int[max-min+1]; for(int i=0;i<size;++i){ ++help[arr[i]-min]; } int cnt=0; int res=0; for(int i=0;i<size;++i){ if(help[arr[i]-min]>cnt){ cnt=help[arr[i]-min]; res=arr[i]; } } return res; } }
C++实现:
1 int maxCount(vector<int> &arr) 2 { 3 int size = arr.size(); 4 int max = INT_MIN; 5 int min = INT_MAX; 6 for (int i = 0; i < size; ++i) 7 { 8 if (max < arr[i]) 9 max = arr[i]; 10 if (min > arr[i]) 11 min = arr[i]; 12 } 13 vector<int> help(max - min + 1); 14 15 for (int i = 0; i < size; ++i) 16 ++help[arr[i]-min]; 17 int cnt = 0; 18 int res = 0; 19 for (int i = 0; i < size; ++i) 20 if (help[arr[i] - min] > cnt) 21 { 22 cnt = help[arr[i] - min]; 23 res = arr[i]; 24 } 25 return res; 26 }
17、合并两个升序链表
(1)非递归
Java实现:
package com.mian.demo; import java.util.Scanner; public class MergeTwoList{ public static void main(String[] args) { MergeTwoList mt=new MergeTwoList(); ListNode list1=mt.createList(); ListNode list2=mt.createList(); mt.printList(list1); mt.printList(list2); ListNode node=mt.mergeList(list1,list2); mt.printList(node); } private ListNode mergeList(ListNode list1,ListNode list2){ if(list1==null&&list2==null){ return null; } if(list1==null){ return list2; } if(list2==null){ return list1; } ListNode first=new ListNode(-1); ListNode cur=first; while(list1!=null&&list2!=null){ if(list1.val<list2.val){ cur.next=list1; list1=list1.next; }else{ cur.next=list2; list2=list2.next; } cur=cur.next; } cur.next=list1!=null?list1:list2; return first.next; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter node value (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
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* createList() 15 { 16 int in; 17 cout << "enter list value (enter 100 to quit):"; 18 cin >> in; 19 ListNode* head = nullptr; 20 if (in == 100) 21 return head; 22 else 23 { 24 head = new ListNode(in); 25 head->next = createList(); 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* mergeList(ListNode* list1, ListNode* list2) 44 { 45 if (!list1 && !list2) 46 return nullptr; 47 if (!list1) 48 return list2; 49 if (!list2) 50 return list1; 51 ListNode* first = new ListNode(-1); 52 ListNode* cur = first; 53 while (list1&&list2) 54 { 55 if (list1->val < list2->val) 56 { 57 cur->next = list1; 58 list1 = list1->next; 59 } 60 else 61 { 62 cur->next = list2; 63 list2 = list2->next; 64 } 65 cur = cur->next; 66 } 67 cur->next = list1 ? list1 : list2; 68 return first->next; 69 } 70 71 int main() 72 { 73 ListNode* node1 = createList(); 74 printList(node1); 75 ListNode* node2 = createList(); 76 printList(node2); 77 ListNode* res = mergeList(node1, node2); 78 printList(res); 79 80 return 0; 81 }
(2)递归
Java实现:
package com.mian.demo; import java.util.Scanner; public class MergeTwoListRecur{ public static void main(String[] args) { MergeTwoListRecur mt=new MergeTwoListRecur(); ListNode list1=mt.createList(); ListNode list2=mt.createList(); mt.printList(list1); mt.printList(list2); ListNode node=mt.mergeList(list1,list2); mt.printList(node); } private ListNode mergeList(ListNode list1,ListNode list2){ if(list1==null&&list2==null){ return null; } if(list1==null){ return list2; } if(list2==null){ return list1; } ListNode head=null; if(list1.val<list2.val){ head=list1; head.next=mergeList(list1.next,list2); }else{ head=list2; head.next=mergeList(list1,list2.next); } return head; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter node value (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int v){ this.val=v; this.next=null; } }
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* createList() 15 { 16 int in; 17 ListNode* head = nullptr; 18 cout << "enter list val (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 = createList(); 26 } 27 return head; 28 } 29 30 void printNode(ListNode* head) 31 { 32 ListNode* p = head; 33 while (p) 34 { 35 cout << p->val << " "; 36 p = p->next; 37 } 38 cout << endl; 39 } 40 41 ListNode* mergeListRecur(ListNode* list1, ListNode* list2) 42 { 43 if (!list1 && !list2) 44 return nullptr; 45 if (list1 == nullptr) 46 return list2; 47 if (list2 == nullptr) 48 return list1; 49 ListNode* head = nullptr; 50 if (list1->val < list2->val) 51 { 52 head = list1; 53 head->next = mergeListRecur(list1->next, list2); 54 } 55 else 56 { 57 head = list2; 58 head->next = mergeListRecur(list1, list2->next); 59 } 60 return head; 61 } 62 63 int main() 64 { 65 ListNode* head1 = createList(); 66 ListNode* head2 = createList(); 67 printNode(head1); 68 printNode(head2); 69 ListNode* head = mergeListRecur(head1, head2); 70 printNode(head); 71 72 return 0; 73 }
18、将数组的后m个数移动为前m个数
Java实现:
package com.mian.demo; public class MoveArrayReverse { public static void main(String[] args) { int[] arr={ 1,2,3,4,5,6,7,8 }; MoveArrayReverse mr=new MoveArrayReverse(); mr.printArray(arr); mr.moveArrayReverse(arr,3); mr.printArray(arr); } private void moveArrayReverse(int[] arr,int n){ int size=arr.length; if(size==0||arr==null){ return; } int m=size-n; reverse(arr,0,m-1); reverse(arr,m,size-1); reverse(arr,0,size-1); } private void reverse(int[] arr,int i,int j){ int size=arr.length; if(size==0||arr==null){ return; } int tmp=0; while(i<j){ tmp=arr[i]; arr[i]=arr[j]; arr[j]=tmp; ++i; --j; } } 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++实现:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 void printArray(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return; 11 for (int i = 0; i < size - 1; ++i) 12 cout << arr[i] << " "; 13 cout << arr[size - 1] << endl; 14 } 15 16 void reverse(vector<int> &arr, int i, int j) 17 { 18 int size = arr.size(); 19 if (size == 0 || arr.empty()) 20 return; 21 int tmp = 0; 22 while (i < j) 23 { 24 tmp = arr[i]; 25 arr[i] = arr[j]; 26 arr[j] = tmp; 27 ++i; 28 --j; 29 } 30 } 31 32 void moveArrayReverse(vector<int> &arr, int n) 33 { 34 int size = arr.size(); 35 if (size == 0 || arr.empty()) 36 return; 37 int m = size - n; 38 reverse(arr, 0, m-1); 39 reverse(arr, m, size-1); 40 reverse(arr, 0, size-1); 41 } 42 43 int main() 44 { 45 vector<int> arr{ 1,2,3,4,5,6,7,8 }; 46 printArray(arr); 47 moveArrayReverse(arr, 3); 48 printArray(arr); 49 50 return 0; 51 }
19、找出数组中出现奇数次的元素:有一个整数数组arr,其中的元素只有一个元素出现奇数次,请找出这个元素。
对于任意一个数k,有k^k = 0,k^0 = k,所以将arr中所有元素进行异或,那么出现次数为偶数的元素异或后都变成了0,出现次数为奇数的元素异或后得到元素本身。
Java实现:
package com.mian.demo; public class OddElement { public static void main(String[] args) { OddElement oe=new OddElement(); int[] arr={1,2,3,4,2,1,4,3,2}; int res=oe.oddElement(arr); System.out.println(res); } private int oddElement(int[] arr){ int res=0; for(int i=0;i<arr.length;++i){ res^=arr[i]; } return res; } }
C++实现:
1 int oddElement(vector<int> &arr) 2 { 3 int res = 0; 4 for (int i = 0; i < arr.size(); ++i) 5 res ^= arr[i]; 6 return res; 7 }
20、使数组中的奇数在左边,偶数在右面
(1)方法一:奇数和偶数之间的相对位置不变
Java实现:
package com.mian.demo; public class OddEven { public static void main(String[] args) { int[] arr={ 0,8,1,2,3,4,5,7,6 }; OddEven oe=new OddEven(); oe.printArray(arr); oe.oddEven(arr); oe.printArray(arr); } private void oddEven(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } int i=0; int j=0; while(i<size){ while(i<size&&!isEven(arr[i])){ ++i; } j=i+1; while(j<size&&isEven(arr[j])){ ++j; } if(j<size){ int tmp=arr[j]; for(int k=j-1;k>=i;--k){ arr[k+1]=arr[k]; } arr[i++]=tmp; }else{ break; } } } private boolean isEven(int num){ if(num%2==0){ return true; } return false; } 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]); } }
package com.mian.demo; public class OddEvenBubble { public static void main(String[] args) { int[] arr={ 0,8,1,2,3,4,5,7,6 }; OddEvenBubble oeb=new OddEvenBubble(); oeb.printArray(arr); oeb.oddEven(arr); oeb.printArray(arr); } private void oddEven(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=0;i<size;++i){ for(int j=size-1;j>i;--j){ if(arr[j]%2==1&&arr[j-1]%2==0){ arr[j-1]=arr[j-1]+arr[j]; arr[j]=arr[j-1]-arr[j]; arr[j-1]=arr[j-1]-arr[j]; } } } } 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++实现:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 void printArray(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return; 11 for (int i = 0; i < size - 1; ++i) 12 cout << arr[i] << " "; 13 cout << arr[size - 1] << endl; 14 } 15 16 bool isEven(int num) 17 { 18 if (num % 2 == 0) 19 return true; 20 return false; 21 } 22 23 void oddEven(vector<int> &arr) 24 { 25 int size = arr.size(); 26 if (size == 0 || arr.empty()) 27 return; 28 int i = 0; 29 int j = 0; 30 while (i < size) 31 { 32 while (i < size && !isEven(arr[i])) 33 ++i; 34 j = i + 1; 35 while (j < size&&isEven(arr[j])) 36 ++j; 37 if (j < size) 38 { 39 int tmp = arr[j]; 40 for (int k = j - 1; k >= i; --k) 41 arr[k + 1] = arr[k]; 42 arr[i++] = tmp; 43 } 44 else 45 break; 46 } 47 } 48 49 int main() 50 { 51 vector<int> arr{ 0,8,1,2,3,4,5,7,6 }; 52 printArray(arr); 53 oddEven(arr); 54 printArray(arr); 55 56 return 0; 57 }
(2)方法二:不保持奇数和偶数之间的相对位置不变
Java实现:
package com.mian.demo; public class OddEven2 { public static void main(String[] args) { int[] arr={ 0,8,1,2,3,4,5,7,6 }; OddEven2 oe=new OddEven2(); oe.printArray(arr); oe.oddEven(arr); oe.printArray(arr); } private void oddEven(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } int start=0; int end=size-1; while(start<end){ while(start<end&&!isEven(arr[start])){ ++start; } while(start<end&&isEven(arr[end])){ --end; } swap(arr,start,end); } } private void swap(int[] arr,int a,int b){ int tmp=arr[a]; arr[a]=arr[b]; arr[b]=tmp; } private boolean isEven(int num){ if(num%2==0){ return true; } return false; } 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++实现:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 void printArray(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return; 11 for (int i = 0; i < size - 1; ++i) 12 cout << arr[i] << " "; 13 cout << arr[size - 1] << endl; 14 } 15 16 bool isEven(int num) 17 { 18 if (num % 2 == 0) 19 return true; 20 return false; 21 } 22 23 void swap(vector<int> &arr, int a, int b) 24 { 25 int tmp = arr[a]; 26 arr[a] = arr[b]; 27 arr[b] = tmp; 28 } 29 30 void oddEven(vector<int> &arr) 31 { 32 int size = arr.size(); 33 if (size == 0 || arr.empty()) 34 return; 35 int start = 0; 36 int end = size - 1; 37 while (start < end) 38 { 39 while (start < end && !isEven(arr[start])) 40 ++start; 41 while (start < end&&isEven(arr[end])) 42 --end; 43 swap(arr[start], arr[end]); 44 } 45 } 46 47 int main() 48 { 49 vector<int> arr{ 0,8,1,2,3,4,5,7,6 }; 50 printArray(arr); 51 oddEven(arr); 52 printArray(arr); 53 54 return 0; 55 }
21、数组a[N],1-N-1这(N-1)个数存放在a[N]中,其中某个数重复一次,找出这个数。时间复杂度不超过O(n)
方法一:
Java实现:
package com.mian.demo; public class OnlyRepeateOnce { public static void main(String[] args) { int[] arr={ 1,2,3,3,4,5,6,7 }; OnlyRepeateOnce oto=new OnlyRepeateOnce(); int rep=oto.onlyRepeateOnce(arr); System.out.println(rep); } private int onlyRepeateOnce(int[] arr){ int size=arr.length; if(size==0||arr==null){ return -1; } int res=0; for(int i=0;i<size;++i){ res^=arr[i]; } for(int i=1;i<size;++i){ res^=i; } return res; } }
C++实现:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 int onlyRepeateOnce(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return -1; 11 int res = 0; 12 for (int i = 0; i < size; ++i) 13 res ^= arr[i]; 14 for (int i = 1; i < size; ++i) 15 res ^= i; 16 return res; 17 } 18 19 int main() 20 { 21 vector<int> arr{ 1,2,3,3,4,5,6,7 }; 22 cout << onlyRepeateOnce(arr) << endl; 23 24 return 0; 25 }
方法二:数学推导法: 不重复时sum=1+2+...+ d + (d+1)...+N;现在less=1+2+...+ d + d + (d+1)+...+(N-1)。sum和less都有N个数,由于less中只有一个重复的数字d,则必有1<=d<=(N-1),sum>less。 sum - less = 0+0+...+ 0 + (-d) + 0...0 + N =(N-d)。所以重复的d=N-(sum-less)。
Java实现:
package com.mian.demo; public class OnlyRepeate { public static void main(String[] args) { int[] arr={ 1,2,3,3,4,5,6,7 }; OnlyRepeate or=new OnlyRepeate(); int res=or.onlyRepeate(arr); System.out.println(res); } private int onlyRepeate(int[] arr){ int size=arr.length; if(size==0||arr==null){ return -1; } int sum=0; int less=0; for(int i=1;i<=size;++i){ sum+=i; } for(int i=0;i<size;++i){ less+=arr[i]; } int res=size-(sum-less); return res; } }
22、一个序列先增后减,求峰值
方法一:
Java实现:
package com.mian.demo; public class GetPeek { public static void main(String[] args) { int[] arr={ 3,4,5,6,7,6,4,1,0 }; GetPeek gp=new GetPeek(); gp.getPeek(arr); } private void getPeek(int[] arr){ int size=arr.length; if(size==0||arr==null){ return; } for(int i=1;i<size;++i){ if(arr[i]<arr[i-1]){ System.out.println(arr[i-1]); break; } } } }
C++实现:
1 #include<iostream> 2 #include<vector> 3 4 using namespace std; 5 6 void getPeek(vector<int> &arr) 7 { 8 int size = arr.size(); 9 if (size == 0 || arr.empty()) 10 return; 11 for (int i = 1; i < size; ++i) 12 if (arr[i] < arr[i - 1]) 13 { 14 15 cout << arr[i - 1] << endl; 16 break; 17 } 18 } 19 20 int main() 21 { 22 vector<int> arr{ 3,4,5,6,7,6,4,1,0 }; 23 getPeek(arr); 24 25 return 0; 26 }
方法二:
Java实现:
package com.mian.demo; public class FindPeek { public static void main(String[] args) { int arr[] = { 0,3,6,9,7,5,2,1 }; FindPeek fp=new FindPeek(); int peek=fp.findPeek(arr,8); System.out.println(peek); } private int findPeek(int[] arr,int n){ return helper(arr,n,0,n-1); } private int helper(int[] arr,int n,int low,int high){ int mid=(low+high)>>1; while(low<=high){ if((mid==0||arr[mid-1]<=arr[mid])&&(mid==n-1||arr[mid+1]<=arr[mid])){ return arr[mid]; }else if(mid>0&&arr[mid-1]>arr[mid]){ high=mid-1; }else{ low=mid+1; } } return -1; } }
C++实现:
1 #include<cstdio> 2 3 int helper(int arr[], int n, int low, int high) 4 { 5 int mid = low + (high - low) / 2; 6 while (low <= high) 7 { 8 if ((mid == 0 || arr[mid - 1] <= arr[mid]) && (mid == n - 1 || arr[mid + 1] <= arr[mid])) 9 return arr[mid]; 10 else if (mid > 0 && arr[mid - 1] > arr[mid]) 11 high = mid - 1; 12 else 13 low = mid + 1; 14 } 15 } 16 17 int findPeek(int arr[], int n) 18 { 19 return helper(arr, n, 0, n - 1); 20 } 21 22 int main() 23 { 24 int arr[] = { 0,3,6,9,7,5,2,1 }; 25 printf("%d ",findPeek(arr, 8)); 26 27 return 0; 28 }
23、用一个for循环打印出一个二维数组
二维数组在内存中默认是按照行存储的,比如一个二维数组{{1,2,3,},{4,5,6}},
它在内存中存储的顺序就是1、2、3、4、5、6,也就是说,对于这6个数组元素,按照从0到5给它们编号的话,
从它们的编号都能推出它们在二维数组中的行号和列号,比如行号即为序号对列数的整数商,列号则为序号对列数取余。
所以别说二维数组了,其它维数组也能用一个for循环打印出来。
Java实现:
package com.mian.demo; public class PrintArray { public static void main(String[] args) { int[][] arr={ {1,2,3,4},{2,3,4,5},{9,6,7,8}}; PrintArray pa=new PrintArray(); pa.printArray(arr,3,4); } private void printArray(int arr[][],int row,int col){ for(int i=0;i<row*col;++i){ System.out.print(arr[i/col][i%col]+" "); } System.out.println(); } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 void printArray(int arr[][4], int row, int col) 6 { 7 for (int i = 0; i < row*col; ++i) 8 cout << arr[i / col][i%col] << " "; 9 cout << endl; 10 } 11 12 int main() 13 { 14 int arr[3][4] = { {1,2,3,4},{2,3,4,5},{9,6,7,8}}; 15 printArray(arr, 3, 4); 16 17 return 0; 18 }
24、递归求数组的和
Java实现:
package com.mian.demo; public class RecurSum { public static void main(String[] args) { RecurSum r=new RecurSum(); int[] arr={9,3,1,5,2}; int sum=r.recurSum(arr,arr.length); System.out.println(sum); } private int recurSum(int[] arr,int n){ if(n==0||arr==null){ return 0; } return recurSum(arr,n-1)+arr[n-1]; } }
C++实现:
1 #include<iostream> 2 3 using namespace std; 4 5 int recurSum(int arr[], int n) 6 { 7 if (n == 0 || arr == nullptr) 8 return 0; 9 return recurSum(arr, n - 1) + arr[n - 1]; 10 } 11 12 int main() 13 { 14 int arr[5] = { 1,2,3,4,5 }; 15 cout << recurSum(arr, 5) << endl; 16 17 return 0; 18 }
25、反转单链表
Java实现:
package com.mian.demo; import java.util.Scanner; public class ReverseList { public static void main(String[] args) { ReverseList rl=new ReverseList(); ListNode head=rl.createList(); rl.printList(head); ListNode last=rl.reverseList(head); rl.printList(last); } private ListNode reverseList(ListNode head){ if(head==null){ return head; } ListNode cur=head; ListNode pre=null; ListNode next=null; while(cur!=null){ next=cur.next; cur.next=pre; pre=cur; cur=next; } return pre; } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter value of list (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int val){ this.val=val; this.next=null; } }
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* createList() 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 = createList(); 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* reverseList(ListNode* head) 44 { 45 if (head == nullptr) 46 return head; 47 ListNode* cur = head; 48 ListNode* pre = nullptr; 49 ListNode* next = nullptr; 50 while (cur) 51 { 52 next = cur->next; 53 cur->next = pre; 54 pre = cur; 55 cur = next; 56 } 57 return pre; 58 } 59 60 int main() 61 { 62 ListNode* head = createList(); 63 printList(head); 64 ListNode* last=reverseList(head); 65 printList(last); 66 67 return 0; 68 }
26、反向输出单链表
Java实现:
package com.mian.demo; import java.util.Scanner; import java.util.Stack; public class ReversePrintList { public static void main(String[] args) { ReversePrintList rpl=new ReversePrintList(); ListNode head=rpl.createList(); rpl.reversePrintList(head); } private void reversePrintList(ListNode head){ if(head==null){ return; } Stack<ListNode> stk=new Stack<>(); ListNode cur=head; while(cur!=null){ stk.push(cur); cur=cur.next; } while(!stk.isEmpty()){ System.out.print(stk.pop().val+" "); } } private ListNode createList(){ int val; ListNode head=null; System.out.println("enter value of list (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; } private void printList(ListNode head){ if(head==null){ return; } ListNode cur=head; while(cur!=null){ System.out.print(cur.val+" "); cur=cur.next; } System.out.println(); } } class ListNode{ public int val; ListNode next; ListNode(){} ListNode(int val){ this.val=val; this.next=null; } }
C++实现:
1 #include<iostream> 2 #include<stack> 3 4 using namespace std; 5 6 class ListNode 7 { 8 public: 9 int val; 10 ListNode* next; 11 ListNode(){} 12 ListNode(int x):val(x),next(nullptr){} 13 }; 14 15 ListNode* createList() 16 { 17 int in; 18 ListNode* head = nullptr; 19 cout << "enter list value (enter 100 to quit):"; 20 cin >> in; 21 if (in == 100) 22 return head; 23 else 24 { 25 head = new ListNode(in); 26 head->next = createList(); 27 } 28 return head; 29 } 30 31 void printList(ListNode* head) 32 { 33 if (head == nullptr) 34 return; 35 ListNode* p = head; 36 while (p) 37 { 38 cout << p->val << " "; 39 p = p->next; 40 } 41 cout << endl; 42 } 43 44 void reversePrintList(ListNode* head) 45 { 46 if (head == nullptr) 47 return; 48 stack<ListNode*> stk; 49 ListNode* p = head; 50 while (p) 51 { 52 stk.push(p); 53 p = p->next; 54 } 55 while (!stk.empty()) 56 { 57 ListNode* node = stk.top(); 58 stk.pop(); 59 cout << node->val << " "; 60 } 61 cout << endl; 62 } 63 64 int main() 65 { 66 ListNode* head = createList(); 67 printList(head); 68 reversePrintList(head); 69 70 return 0; 71 }
27、输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
方法一:利用位操作来简化题目,即给所有输出方式进行编号(1 ~ 2^n-1)
0 0 1 --> a
0 1 0 --> b
0 1 1 --> ab
1 0 0 --> c
1 0 1 --> ac
1 1 0 --> bc
1 1 1 --> abc
Java实现:
package com.mian.demo; public class PrintAllCombination { public static void main(String[] args) { String s="abc"; PrintAllCombination pac=new PrintAllCombination(); pac.printAllCombination(s); } private void printAllCombination(String s){ int size=s.length(); int comb_count=1<<size; for(int i=1;i<comb_count;++i){ for(int j=0;j<size;++j){ if((i&(1<<j))!=0){ System.out.print(s.charAt(j)+" "); } } System.out.println(); } } }
C++实现:
1 #include<stdio.h> 2 #include<string.h> 3 4 void printAllCombination(char *s) 5 { 6 int len = strlen(s); 7 int comb_count = 1 << len; 8 9 for (int i = 1; i < comb_count; ++i) 10 { 11 for (int j = 0; j < len; ++j) 12 if (i&(1 << j)) 13 printf("%c", s[j]); 14 printf(" "); 15 } 16 } 17 18 int main() 19 { 20 char *s = "abc"; 21 printAllCombination(s); 22 23 return 0; 24 }
方法二:假设想在长度为n的字符串中求m个字符的组合。 先从头扫描字符串的第一个字符。针对第一个字符,有两种选择:一是把这个字符放到组合中去,接下来需要在剩下的n-1个字符中选取m-1个字符;二是不把这个字符放到组合中去,接下来需要在剩下的n-1个字符中选择m个字符。
Java实现:
package com.mian.demo; import java.util.ArrayList; public class Combinations { public static void main(String[] args) { String str="abc"; Combinations cbs=new Combinations(); cbs.combinations(str); } private void combinations(String str){ if(str.isEmpty()){ return; } int size=str.length(); StringBuilder sb=new StringBuilder(); for(int i=0;i<size;++i){ helper(str,0,i,sb); } } private void helper(String str, int index, int num,StringBuilder sb){ if(num==-1){ System.out.println(sb.toString()); return; } if(index==str.length()){ return; } sb.append(str.charAt(index)); helper(str,index+1,num-1,sb); sb.deleteCharAt(sb.length()-1) ; helper(str,index+1,num,sb); } }
C++实现:
1 #include<iostream> 2 #include<cstring> 3 #include<vector> 4 5 using namespace std; 6 7 void helper(char *str, int n, vector<char> &vec) 8 { 9 if (str == nullptr || (n != 0 && *str == '