給定乙個陣列arr,全是正數;乙個整數aim,求累加和等 於aim的,最長子陣列,要求額外空間複雜度o(1),時間 複雜度o(n)
思路就是利用兩個指標,來進行滑動視窗的計算。
#include
#include
#include
using
namespace std;
class
solution
int l =0;
int r =0;
int sum = nums[0]
;int len =0;
while
(r < nums.
size()
)else
if(sum < aim)
else
}return len;}}
;int
main()
; solution s;
cout<
getmaxlength
(nums,6)
<
return0;
}
ps:r和l均指向陣列中的第乙個元素,此時sum=nums[0],並且len=0,作為乙個開始的值。用int_min也可以,但是題目要求找不到返回0,就只能這樣定義了。
給定乙個陣列arr,值可正,可負,可0;乙個整數aim,求累加和小於等於aim的,最長子陣列,要求時間複雜度o(n)
#include
#include
#include
using
namespace std;
class
solution
//sums[i]:i開頭的所有子陣列的最小累加和
//ends[i]:取得最小累加和對應的右邊界
vector<
int> sums,ends;
sums.
resize
(nums.
size()
);ends.
resize
(nums.
size()
);//兩個陣列的最後乙個元素可直接寫出
sums[nums.
size()
-1]= nums[nums.
size()
-1];
ends[nums.
size()
-1]= nums.
size()
-1;//從後往前生成陣列
for(
int i = nums.
size()
-2; i >=
0; i--
)else
}//具體的處理邏輯
int r =0;
int sum =0;
int len =0;
for(
int start =
0; start < nums.
size()
; start++
) sum -
= r > start ? nums[start]:0
;//擴不動的話,減nums[i],判斷從nums[i+1]開始能不能繼續擴(這裡是加速的關鍵)
len =
max(len, r - start)
;//儲存len的最大值
r =max(r, start +1)
;//處理一開始就擴不動的情況
}return len;}}
;int
main()
; solution s;
cout<
maxlengthawesome
(nums,6)
;}
ps:臥槽這玩意真難理解!!!下面是所測例子的**模擬過程:
換錢的方法數
【題目】 給定陣列arr,arr中所有的值都為正數且不重複。每個值代表 一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定一 個整數aim代表要找的錢數,求換錢有多少種方法。
【舉例】 arr=[5,10,25,1],aim=0。 組成0元的方法有1種,就是所有面值的貨幣都不用。所以返回1。 arr=[5,10,25,1],aim=15。 組成15元的方法有6種,分別為3張5元、1張10元+1張5元、1張 10元+5張1元、10張1元+1張5元、2張5元+5張1元和15張1元。所 以返回6。 arr=[3,5],aim=2。 任何方法都無法組成2元。所以返回0
ps:這個題是典型的動態規劃問題,也就是常說的找零問題。
#include
#include
//#include
using
namespace std;
class
solution
return dp[n]
[amount];}
};intmain()
; solution s;
cout<
change(10
,nums)
;}
其中的dp[i][j]表示:使用cions中前i個硬幣,湊出金額j,有dp[i][j]種湊法。
base case,dp[…][0] = 1表示:不用硬幣和用前i個硬幣,無論如何湊出0的方法都只有1種。dp[0][…] = 0表示:不使用任何硬幣,就無法湊出任何金額。如何轉移**中有注釋。下圖展示的是例子中的dp生成過程:
;}排成一條線的紙牌博弈問題
【題目】 給定乙個整型陣列arr,代表數值不同的紙牌排成一條線。玩家a和玩家b依次拿走 每張紙牌,規定玩家a先拿,玩家b後拿,但是每個玩家每次只能拿走最左或最右 的紙牌,玩家a和玩家b都絕頂聰明。請返回最後獲勝者的分數。
【舉例】 arr=[1,2,100,4]。 開始時玩家a只能拿走1或4。如果玩家a拿走1,則排列變為[2,100,4],接下來玩 家b可以拿走2或4,然後繼續輪到玩家a。如果開始時玩家a拿走4,則排列變為 [1,2,100],接下來玩家b可以拿走1或100,然後繼續輪到玩家a。玩家a作為絕頂 聰明的人不會先拿4,因為拿4之後,玩家b將拿走100。所以玩家a會先拿1,讓排 列變為[2,100,4],接下來玩家b不管怎麼選,100都會被玩家a拿走。玩家a會獲勝, 分數為101。所以返回101。 arr=[1,100,2]。 開始時玩家a不管拿1還是2,玩家b作為絕頂聰明的人,都會把100拿走。玩家b會 獲勝,分數為100。所以返回
#include
#include
using namespace std;
class solution
// 斜著遍歷陣列
for(
int l =
2; l <= n; l++
)else}}
pair<
int,
int> res = dp[0]
[n-1];
return res.first;}}
;int
main()
; solution s;
cout<
stonegame
(nums)
;}
下面的這個版本,其實就是用兩個表,這樣表中的元素就可以分別表示,而不是用pair來表示,兩種方法本質上沒有區別的。
#include
#include
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)
using namespace std;
intgetresult
(vector<
int>
,int);
intmain()
cout <<
getresult
(arr,n)
<< endl;
}int
getresult
(vector<
int>arr,
int n)
}//返回f和s中較大的乙個
return
max(f[0]
[n -1]
, s[0]
[n -1]);}
ps:好難~ 左神牛課網講座第二發 演算法講解
從5隨機到7隨機及其擴充套件 題目 給定乙個等概率隨機產生1 5的隨機函式rand1to5如下 public intrand1to5 除此之外不能使用任何額外的隨機機制,請用rand1to5實現等概率隨機產生1 7的隨機函式rand1to7。補充題目 給定乙個以p概率產生0,以1 p概率產生1的隨機...
左神牛課網講座第一發 演算法講解
給定 乙個字串str和它的 乙個最長回 文 子串行strlps,返回字串str在任意 位置新增最少字元後,整體都是回 文串的其中 一種結果。例如 str ab1c2de34f3ghj21kl strlps 1234321 返回 ablk1c2dejhg3f4f3ghjed2c1klba 解答 1,依...
左神初級班 (二)
實現一種狗貓佇列的結構,要求如下 使用者可以呼叫add方法將cat類或dog類的例項放入佇列中 使用者可以呼叫pollall方法,將佇列中所有的例項按照進佇列的先後順序依次彈出 使用者可以呼叫polldog方法,將佇列中dog類的例項按照進佇列的先後順序依次彈出 使用者可以呼叫pollcat方法,將...