![](/img/trans.png)
[英]I am stuck in this binary search problem in geeks for geeks (time limit exceeded)
[英]Segmentation Fault (SIGSEGV) in Geeks for Geeks problem
嗨,我正在嘗試使用 brute for 方法解決 Geeks for Geeks 上的問題,所以問題陳述是,
給定一個正整數數組。 你的任務是找到數組中的領導者。 注意:如果數組的元素大於或等於其右側的所有元素,則該元素是領導者。 此外,最右邊的元素始終是領導者。
輸入:輸入的第一行包含一個整數 T,表示測試用例的數量。 T 測試用例的描述如下。 每個測試用例的第一行包含一個整數 N,表示數組的大小。 第二行包含 N 個空格分隔的整數 A1, A2, ..., AN 表示數組的元素。
輸出:打印所有領導者。
Constraints:
1 <= T <= 100,
1 <= N <= 107,
0 <= Ai <= 107
Example:
Input:
3
6
16 17 4 3 5 2
5
1 2 3 4 0
5
7 4 5 7 3
Output:
17 5 2
4 0
7 7 3
我開發了我的解決方案如下,
#include <iostream>
using namespace std;
long **leader;
long *cond;
void leader_in_array(long *A,long N,long i) {
long check = 0, count = 0;
for (long j = N - 1; j >= 0 ; j--)
{
if (check <= A[j])
{
check = A[j];
leader[i][count] = check;
count++;
}
}
cond[i] = count;
}
int main() {
long T;
cin >> T;
leader = new long*[T];
cond = new long(T);
for (long i = 0; i < T; i++)
{
long N;
cin >> N;
long *A = new long(N);
leader[i] = new long[N];
for (long j = 0; j < N; j++)
{
cin >> A[j];
}
leader_in_array(A, N, i);
delete [] A;
}
for (long i = 0; i < T; i++)
{
for (long j = cond[i] - 1; j >=0 ; j--)
{
cout << leader[i][j] << " ";
}
cout << endl;
}
delete [] leader;
delete [] cond;
return 0;
}
它適用於測試用例,但是當我嘗試在實際案例中提交我的代碼時,我收到錯誤
分段錯誤 (SIGSEGV)
我明白它是什么,但無法確定我在哪里做錯了。
問題是N
高達 10**7 (10,000,000),但您只為A
和leader
元素分配了 10 個元素。 您必須分配足夠的元素。
要實現這一點,有以下幾點:
A
在堆棧上分配。 在某些環境中,堆棧限制為幾 MB,因此應將其標記為static
以將其從堆棧中移除。int leader[100][10];
到int leader[100][10000000];
將導致告訴他們分配太多內存。 為避免這種情況,您應該只分配一個查詢並在閱讀后立即回答每個查詢,而不是保存所有查詢的答案。該錯誤已向您指出,但不值得修復。 您的嘗試比實際需要的復雜得多,似乎有一個更簡單、簡單的解決方案:一個循環,以相反的順序搜索數組,並在每次發現高於所見最高值的值時進行跟蹤迄今為止。 就是這樣。
問題指定這些值是正數,因此我們可以簡單地將低水印初始化為 0,並使用它運行。
void all_leaders_in_array(int *arr, size_t size)
{
int highest=0;
while (size > 0)
{
if (arr[--size] > highest)
{
// arr[size] is a "leader" value here,
// do whatever you want with it, print it, etc...
highest=arr[size];
}
}
}
就是這樣。 以上將查找數組中所有所謂的“領導者”,使用一個,簡單的循環,沒有任何復雜的邏輯。 根據定義,這會獲取數組中高於所有以下值的所有值。 當向后搜索數組時,解決方案變得更加簡單。 只需按倒序跟蹤所見的最高值,然后收工。
我在問題中找不到任何說明領導者值是否必須按其原始順序顯示的內容。 上面的代碼將以相反的順序查找/打印值。 如果必須按照它們的原始出現順序報告它們,只需將每個值保存在一個單獨的數組中,然后以相反的順序打印該數組。 任務完成。
在您更新的代碼中,您似乎在long *A = new long(N);
處有一個錯字long *A = new long(N);
我相信你想要long *A = new long[N];
無論如何,你把事情復雜化了。 首先,使用std::vector
消除所有內存分配的東西。 其次,完全處理每個測試用例——也就是說,在所有測試用例完成之前不要保存打印。 運行一個測試用例並打印該測試用例的結果。 重復。
下面是一個例子:
#include <iostream>
#include <vector>
#include <cstdint>
int main() {
uint32_t T;
std::cin >> T;
while (T--) {
uint32_t N;
std::cin >> N;
// Create input vector and read data
// The parameter tells the vector the initial size
std::vector<uint32_t> data(N);
for (auto i = 0; i < N; i++) {
std::cin >> data[i];
}
// max is the maximum value at each iteration of the loop
// Initialized to the last value of the array
uint32_t max = data.back();
std::vector<uint32_t> results;
// Move backwards through the input (i.e. right to left)
for (auto it = data.rbegin(); it != data.rend(); it++) {
// If current value is > any value to the right
if (*it >= max) {
results.push_back(*it);
max = *it;
}
}
// Print in reverse order before moving on to next test case
for (auto it = results.rbegin(); it != results.rend(); it++) {
std::cout << *it << " ";
}
std::cout << "\n";
}
return 0;
}
注意:如果不要求按一定順序打印結果,可以去掉results
向量,找到時只打印一個數字。
此外,您可以在主循環之前創建一次向量,根據需要調整它們的大小。 不確定這會節省多少執行時間。
#include <iostream>
#include <stack>
using namespace std;
void leader_in_array(long *A,long N) {
long check = 0;
stack<long> leader;
for (long j = N - 1; j >= 0 ; j--)
{
if (check <= A[j])
{
check = A[j];
leader.push(check);
}
}
while (leader.empty() == false)
{
cout << leader.top() << " ";
leader.pop();
}
}
int main() {
long T;
cin >> T;
for (long i = 0; i < T; i++)
{
long N;
cin >> N;
long A[N];
for (long j = 0; j < N; j++)
{
cin >> A[j];
}
leader_in_array(A, N);
cout << endl;
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.