《剑指offer》-- 复杂链表的复制、字符串的排列、数组中出现次数超过一半的数字、连续子数组的最大和
一、復雜鏈表的復制:
參考牛客網的chancy:https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba
1、題目:
輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
2、解題思路:
3、代碼實現:
public class Test12 {public RandomListNode Clone(RandomListNode pHead){if(pHead == null){return null;}RandomListNode currentNode = pHead;//1、遍歷鏈表,復制每個節點,如復制節點A得到A1,將結點A1插到節點A后面;while(currentNode!=null){RandomListNode cloneNode = new RandomListNode(currentNode.label);RandomListNode nextNode=currentNode.next;currentNode.next=cloneNode;cloneNode.next=nextNode;currentNode=nextNode;}//2、重新遍歷鏈表,復制新結點的隨機指針給新結點,如A1.random=A.random.next;currentNode=pHead;while(currentNode!=null){currentNode.next.random = currentNode.random == null?null:currentNode.random.next;currentNode=currentNode.next.next;}//3、拆分鏈表,將鏈表拆分為為原鏈表和復制后的鏈表currentNode=pHead;RandomListNode pCloneHead= pHead.next;while(currentNode!=null){RandomListNode cloneNode=currentNode.next;currentNode.next=cloneNode.next;cloneNode.next=currentNode.next==null?null:currentNode.next.next;currentNode=currentNode.next;}return pCloneHead;}}class RandomListNode {int label;RandomListNode next = null;RandomListNode random = null;RandomListNode(int label) {this.label = label;} }?
?
二、字符串的排列:
1、題目:
輸入入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
2、解題思路:
參考鏈接:牛客網的HAHA7877:https://www.nowcoder.com/questionTerminal/fe6b651b66ae47d7acce78ffdd9a96c7
3、代碼實現:
public class Test14 {public ArrayList<String> Permutation(String str) {List<String> res= new ArrayList<>();if(str!=null && str.length()>0){PermutationHelper(str.toCharArray(),0,res);Collections.sort(res);}return (ArrayList) res;}private void PermutationHelper(char[] charArray, int i, List<String> list) {if(i==charArray.length-1){String str = String.valueOf(charArray);if(!list.contains(str)){list.add(str);}}else{for(int j=i;j<charArray.length;j++){swap(charArray,i,j);PermutationHelper(charArray,i+1,list);swap(charArray,i,j);}}}private void swap(char[] charArray, int i, int j) {char temp=charArray[i];charArray[i]=charArray[j];charArray[j]=temp;} }?
?
三、數組中出現次數超過一半的數字
1、題目:
中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由于數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。2
2、解題思路:
由于目標數 超過數組長度的一半,對數組同時去掉兩個不同的數字,到最后剩下的一個數就是該數字。在其基礎上把最后剩下的數組回到原來的數組中,將數組遍歷一遍統計出現次數進行最終判斷。
3、代碼是實現:
public class Test15 {//方法二:public int MoreThanHalfNum_Solution(int [] array) {int length = array.length;if(array==null || length==0){return 0;}int result=array[0];int times =1;for(int i=1;i<length;i++){if(times==0){result = array[i];times = 1;}else{if(result == array[i]){times++;}else{times--;}}}times=0;for(int i=0;i<length;i++){if(result==array[i]){times++;}}if(times*2<=length){return 0;}return result;}//方法一:public int MoreThanHalfNum_Solution1(int [] array) {int length=array.length;if(array== null || length<=0){return 0;}if(length==1){return array[0];}int[] tempArray = array.clone();for(int i=0;i<length;i++){if(tempArray[i]==0){continue;}for(int j=i+1;j<length;j++){if(tempArray[i]!=tempArray[j] && tempArray[j]!=0){tempArray[i]=0;//此處用0代表抹去該數字tempArray[j]=0;break;}}}//找出未被抹去的數字int result = 0;for(int i=0;i<length;i++){if(tempArray[i]!=0){result = tempArray[i];break;}}int times=0;for(int i=0;i<length;i++){if(result==array[i]){times++;}}if(times*2<=length){return 0;}return result;} }?
?
四、連續子數組的最大和:
1、題目:
一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,并期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。給一個數組,返回它的最大連續子序列的和,你會不會被他忽悠住?(子向量的長度至少是1)
2、代碼實現:
public class Test17 {//方法一:public int FindGreatestSumOfSubArray(int[] array) {if(array.length==0 || array==null){return 0;}int curSum=0;int manSun=0x80000000;//最小的負數-0for(int i=0;i<array.length;i++){if(curSum<=0){curSum=array[i];//記錄當前最大值}else{curSum+=array[i];}if(curSum>manSun){manSun=curSum;}}return manSun;}//方法二:public int FindGreatestSumOfSubArray2(int[] array) {int res=array[0];//記錄當前所有子數組的和的最大值int max=array[0];//包含array[i]的連續數組最大值for(int i=1;i<array.length;i++){max=Math.max(max+array[i],array[i]);res=Math.max(res, max);}return res;} }?
總結
以上是生活随笔為你收集整理的《剑指offer》-- 复杂链表的复制、字符串的排列、数组中出现次数超过一半的数字、连续子数组的最大和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《剑指offer》-- 从上往下打印二叉
- 下一篇: 《剑指offer》-- 二叉树的下一个结