日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《剑指offer》-- 和为S的连续整数序列、和为S的两个数字、左旋转字符串、翻转单词顺序列

發布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《剑指offer》-- 和为S的连续整数序列、和为S的两个数字、左旋转字符串、翻转单词顺序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、和為S的連續整數序列:

1、題目:

小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他并不滿足于此,他在想究竟有多少種連續的正數序列的和為100(至少包括兩個數)。沒多久,他就得到另一組連續正數和為100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和為S的連續正數序列?

2、解題思路:

參考牛客網的“丁滿歷險記”:https://www.nowcoder.com/questionTerminal/c451a3fd84b64cb19485dad758a55ebe

1)由于我們要找的是和為S的連續正數序列,因此這個序列是個公差為1的等差數列,而這個序列的中間值代表了平均值的大小。假設序列長度為n,那么這個序列的中間值可以通過(S / n)得到,知道序列的中間值和長度,也就不難求出這段序列了。

2)滿足條件的n分兩種情況:

n為奇數時,序列中間的數正好是序列的平均值,所以條件為:(n & 1) == 1 && sum % n == 0;

n為偶數時,序列中間兩個數的平均值是序列的平均值,而這個平均值的小數部分為0.5,所以條件為:(sum % n) * 2 == n.

3)由題可知n >= 2,那么n的最大值是多少呢?我們完全可以將n從2到S全部遍歷一次,但是大部分遍歷是不必要的。為了讓n盡可能大,我們讓序列從1開始,

根據等差數列的求和公式:S = (1 + n) * n / 2,得到.

4)最后舉一個例子,假設輸入sum = 100,我們只需遍歷n = 13~2的情況(按題意應從大到小遍歷),n = 8時,得到序列[9, 10, 11, 12, 13, 14, 15, 16];n? = 5時,得到序列[18, 19, 20, 21, 22]。

3、代碼實現:時間復雜度為

public class Test28 {public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();for(int n = (int) Math.sqrt(2*sum);n>=2;n--){if((n&1)==1 && sum%n==0 || (sum%n)*2==n){ArrayList<Integer> list1 = new ArrayList<Integer>();for(int j=0,k=(sum/n)-(n-1)/2;j<n;j++,k++){list1.add(k);}list.add(list1);}}return list;} }

4、第二種解法:雙指針技術:

就是相當于有一個窗口,窗口的左右兩邊就是兩個指針,我們根據窗口內值之和來確定窗口的位置和寬度。

public class Solution {public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {//存放結果ArrayList<ArrayList<Integer> > result = new ArrayList<>();//兩個起點,相當于動態窗口的兩邊,根據其窗口內的值的和來確定窗口的位置和大小int plow = 1,phigh = 2;while(phigh > plow){//由于是連續的,差為1的一個序列,那么求和公式是(a0+an)*n/2int cur = (phigh + plow) * (phigh - plow + 1) / 2;//相等,那么就將窗口范圍的所有數添加進結果集if(cur == sum){ArrayList<Integer> list = new ArrayList<>();for(int i=plow;i<=phigh;i++){list.add(i);}result.add(list);plow++;//如果當前窗口內的值之和小于sum,那么右邊窗口右移一下}else if(cur < sum){phigh++;}else{//如果當前窗口內的值之和大于sum,那么左邊窗口右移一下plow++;}}return result;} }

?

二、和為S的兩個數字:

1、題目:

輸入一個遞增排序的數組和一個數字S,在數組中查找兩個數,使得他們的和正好是S,如果有多對數字的和等于S,輸出兩個數的乘積最小的。

2、解題思路:

找到的第一組(相差最大的)就是乘積最小的。可以這樣證明:考慮x+y=C(C是常數),x*y的大小。
不妨設y>=x,y-x=d>=0,即y=x+d, 2x+d=C, x=(C-d)/2, x*y=x(x+d)=(C-d)(C+d)/4=(C^2-d^2)/4,
也就是x*y是一個關于變量d的二次函數,對稱軸是y軸,開口向下。d是>=0的,d越大, x*y也就越小。

3、代碼實現:

public class Test29 {public static ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {ArrayList<Integer> list = new ArrayList<Integer>();int start = 0;int end = array.length-1;while(start<end){if(array[start]+array[end] == sum){list.add(array[start]);list.add(array[end]);break;}while(start<end && array[start]+array[end]>sum){end--;}while(start<end && array[start]+array[end]<sum){start++;}}return list;} }

?

?

三、左旋轉字符串:

1、題目:

匯編語言中有一種移位指令叫做循環左移(ROL),現在有個簡單的任務,就是用字符串模擬這個指令的運算結果。對于一個給定的字符序列S,請你把其循環左移K位后的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環左移3位后的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!

2、代碼實現:

public class Test27 {public String LeftRotateString(String str,int n) {int len=str.length();if(str==null || len==0){return str;}n=n%len;len=len+n;str+=str;return str.substring(n,len);} }

3、其他解法:

很顯然,上面的解法雖然能夠能到我們想要的答案,但是這道題想考察的知識點應該不是這個,

這道題考的核心是應聘者是不是可以靈活利用字符串翻轉。假設字符串abcdef,n=3,設X=abc,Y=def,所以字符串可以表示成XY,如題干,問如何求得YX。假設X的翻轉為XT,XT=cba,同理YT=fed,那么YX = (XT YT)T,三次翻轉后可得結果。

//第二種解法:利用YX=(XTYT)Tpublic String LeftRotateString(String str,int n) {int len = str.length();if(str == null || n==0 || len==0)return str;n=n%len;char[] array = str.toCharArray();reverse(array,0,n-1);reverse(array, n, len-1);reverse(array, 0, len-1);StringBuilder stringBuilder = new StringBuilder();for(char c:array)stringBuilder.append(c);return stringBuilder.toString();}public void reverse(char[] array,int low,int high){char temp;while(low<high){temp = array[low];array[low]=array[high];array[high]=temp;low++;high--;}}

?

四、翻轉單詞順序列:

1、題目:

牛客最近來了一個新員工Fish,每天早晨總是會拿著一本英文雜志,寫些句子在本子上。同事Cat對Fish寫的內容頗感興趣,有一天他向Fish借來翻看,但卻讀不懂它的意思。例如,“student. a am I”。后來才意識到,這家伙原來把句子單詞的順序翻轉了,正確的句子應該是“I am a student.”。Cat對一一的翻轉這些單詞順序可不在行,你能幫助他么?

2、解題方法:

看代碼注釋。

3、代碼實現:

public class Test26 {//第二種解法:先反轉整個個句子,在反轉每個單詞public String ReverseSentence(String str) {if(str.trim().equals("")) return str;char[] chars=str.toCharArray();reverse(chars,0,chars.length-1);//翻轉整個句子int blank=-1;//第一個空格符的位置int nextBlank=-1;第二個空格符的位置//翻轉每個單詞for(int i=0;i<chars.length;i++){if(chars[i]==' '){nextBlank = i;reverse(chars,blank+1,nextBlank-1);blank=nextBlank;}}//翻轉最后一個單詞reverse(chars,blank+1,chars.length-1);return new String(chars);}public void reverse(char[] chars,int low,int high){while(high>low){char temp = chars[low];chars[low]=chars[high];chars[high]=temp;low++;high--;}}//第一種解法:public String ReverseSentence1(String str) {if(str.trim().equals("")) return str;String[] strArray=str.split(" ");StringBuilder builder = new StringBuilder();for(int i=strArray.length;i>0;i--){builder.append(strArray[i-1]+" ");}return builder.substring(0,builder.length()-1);} }

?

總結

以上是生活随笔為你收集整理的《剑指offer》-- 和为S的连续整数序列、和为S的两个数字、左旋转字符串、翻转单词顺序列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。