Arrays are the most basic data structures. array operations are the most frequently used by programmers. Here we will write some common operations as functions. Array summation
Given an integer array a containing n elements, calculate the sum of all elements in. You may think it is very simple. Yes, it is indeed simple, but why? there are two reasons. first, this question requires recursion and only one line of code is used. Second, this is the first interview question in my life. it is of special significance.
To put it simply, there are two situations:
If the number of array elements is 0, the sum is 0.
If the number of array elements is n, first obtain the sum of the first n-1 elements, and then add a [n-1.
The code is as follows:
// Array summation
Int sum (int * a, int n)
{
Return n = 0? 0: sum (a, n-1) + a [n-1];
}
Returns the maximum and minimum values of an array.
Given an integer array a containing n elements, find the maximum and minimum values.
The general practice is to traverse each time and find the maximum and minimum values respectively, but here I want to talk about Divide and couquer and Divide the array into the left and right parts, first obtain the maximum and minimum values of the left half, then obtain the maximum and minimum values of the right half, and then combine them to obtain the maximum and minimum values of the population. This is a recursive process. for the left and right parts after the division, repeat the process until only one or two elements are left in the division interval.
The code is as follows:
// Calculate the maximum and minimum values of the array. The Returned values are in maxValue and minValue.
Void MaxandMin (int * a, int l, int r, int & maxValue, int & minValue)
{
If (l = r) // There is only one element between l and r.
{
MaxValue = a [l];
MinValue = a [l];
Return;
}
If (l + 1 = r) // There are only two elements between l and r.
{
If (a [l]> = a [r])
{
MaxValue = a [l];
MinValue = a [r];
}
Else
{
MaxValue = a [r];
MinValue = a [l];
}
Return;
}
Int m = (l + r)/2; // calculates the midpoint
Int lmax; // The maximum value of the left half
Int lmin; // minimum value of the left half
MaxandMin (a, l, m, lmax, lmin); // recursive calculation of the left half
Int rmax; // maximum value of the right half
Int rmin; // minimum value of the right half
MaxandMin (a, m + 1, r, rmax, rmin); // recursive calculation of the right half
MaxValue = max (lmax, rmax); // The total maximum value.
MinValue = min (lmin, rmin); // The total minimum value.
}
Returns the maximum and secondary values of the array.
Given an integer array containing n elements, calculate the maximum value and the secondary limit.
The idea is similar to the previous question. We also use the divide and conquer method. if we don't talk about it much, let's look at the code:
The code is as follows:
// Calculate the maximum value and secondary limit of the array. The Returned values are in max and second.
Void MaxandMin (int * a, int left, int right, int & max, int & second)
{
If (left = right)
{
Max = a [left];
Second = a [left];
}
Else if (left + 1 = right)
{
Max = a [left]> a [right]? A [left]: a [right];
Second = a [left] <a [right]? A [left]: a [right];
}
Else
{
Int mid = left + (right-left)/2;
Int leftmax;
Int leftmin;
MaxandMin (a, left, mid, leftmax, leftmin );
Int rightmax;
Int rightmin;
MaxandMin (a, mid + 1, right, rightmax, rightmin );
Max = leftmax> rightmax? Leftmax: rightmax;
Second = leftmax <rightmax? Leftmax: rightmax;
}
}
Evaluate the element that appears more than half of the number of times in the array
Given an array of n integer elements a, where an element appears more than n/2, evaluate this element. It is said to be a interview question from Baidu.
Set a counter of the current value and current value, initialize the current value as the first element of the array, the counter value is 1, and then traverse the entire array from the second element, for each Retrieved value a [I].
If a [I] = currentValue, the counter value is added to 1.
If a [I]! = CurrentValue, the counter value is reduced by 1. if the counter value is smaller than 0, the current value is updated to a [I] and the counter value is reset to 1.
The code is as follows:
// Locate the element that appears more than half of the number of times in the array
Int Find (int * a, int n)
{
Int curValue = a [0];
Int count = 1;
For (int I = 1; I
Another method is to sort the array first, and then take the intermediate element, because if the number of an element exceeds half, the element must occupy the middle position of the array after sorting the array.
Returns the shortest distance of the element in the array.
Given an integer array containing n elements, find the two elements x and y in the array to minimize the abs (x-y) value.
Sort the array first, and then traverse it once:
The code is as follows:
Int compare (const void * a, const void * B)
{
Return * (int *) a-* (int *) B;
}
Void MinimumDistance (int * a, int n)
{
// Sort
Qsort (a, n, sizeof (int), compare );
Int I; // Index of number 1
Int j; // Index of number 2
Int minDistance = numeric_limits : Max ();
For (int k = 0; k <n-1; ++ k)
{
If (a [k + 1]-a [k] <minDistance)
{
MinDistance = a [k + 1]-a [k];
I = a [k];
J = a [k + 1];
}
}
Cout <"Minimum distance is:" <minDistance <endl;
Cout <"I =" <I <"j =" <j <endl;
}
Evaluate the common elements of two ordered arrays
Given two ordered (non-descending) integer arrays a and B containing n elements, find their common elements, such as a = 0, 1, 2, 3, 4 and B = 1, 3, 5, 7, 9, output 1, 3.
Take full advantage of the ordered nature of arrays, use two pointers I and j to point to a and B respectively, compare a [I] and B [j], and move the pointer according to the comparison result, there are three situations:
A [I] <B [j], then I increases by 1 and continues the comparison.
A [I] = B [j], then I and j both add 1 and continue the comparison.
A [I]
Repeat the preceding process until I or j reaches the end of the array.
The code is as follows:
// Find the common elements of the two arrays
Void FindCommon (int * a, int * B, int n)
{
Int I = 0;
Int j = 0;
While (I <n & j <n)
{
If (a [I] <B [j])
++ I;
Else if (a [I] = B [j])
{
Cout <a [I] <endl;
++ I;
++ J;
}
Else // a [I]> B [j]
++ J;
}
}
There are other solutions to this problem, such as Binary Search for any element in a in B, because a has n elements, logn is required for Binary Search in B. Therefore, the time complexity of finding all the same elements is O (nlogn ).
In addition, as long as B is ordered, it doesn't matter whether a is ordered, because we only do Binary Search in B. If a is also ordered, it would be a little slow to use the above method, because if an element in a is k in B, therefore, the position of the next element in B in a must be on the right side of k. Therefore, this search space can be reduced based on the last search result, instead of still searching in B. That is, if both a and B are ordered, the code can make the following changes to record the position of the elements in B during the last search as the starting point of the next search.
Evaluate the common elements of the three arrays
Given three integer arrays a, B, and c that contain n elements, calculate their minimum common element.
If the three arrays are ordered, you can set the three pointers to point to the headers of the three arrays, and then move the pointer based on the values indicated by the three pointers to find the common element.
The code is as follows:
// Common elements of the three arrays-find the smallest element
Void FindCommonElements (int a [], int B [], int c [], int x, int y, int z)
{
For (int I = 0, j = 0, k = 0; I <x & j <y & k <z ;)
{
If (a [I] <B [j])
{
I ++;
}
Else // a [I]> = B [j]
{
If (B [j] <c [k])
{
J ++;
}
Else // B [j]> = c [k]
{
If (c [k] <a [I])
{
K ++;
}
Else // c [k]> = a [I]
{
Cout <c [k] <endl;
Return;
}
}
}
}
Cout <"Not found! "<Endl;
}
If the three arrays are unordered, sort a and B first, and then perform binary search for any element in c in B and c.
The code is as follows:
// Find the unique common element in 3 arrays
// O (NlogN)
Int UniqueCommonItem (int * a, int * B, int * c, int n)
{
// Sort array
Qsort (a, n, sizeof (int), compare); // NlogN
// Sort array B
Qsort (B, n, sizeof (int), compare); // NlogN
// For each element in array c, do a binary search in a and B
// This is up to a complexity of N * 2 * logN
For (int I = 0; I <n; I ++)
{
If (BinarySearch (a, n, c [I]) & BinarySearch (B, n, c [I])
Return c [I];
}
Return-1; // not found
}
You can also sort a and perform binary search for any element in B and c in.
The code is as follows:
// Find the unique common element in 3 arrays
// O (NlogN)
Int UniqueCommonItem1 (int * a, int * B, int * c, int n)
{
// Sort array
Qsort (a, n, sizeof (int), compare); // NlogN
// Space for time
Bool * bb = new bool [n];
Memset (bb, 0, n );
Bool * bc = new bool [n];
Memset (bb, 0, n );
// For each element in B, do a BS in a and mark all the common element
For (int I = 0; I <n; I ++) // NlogN
{
If (BinarySearch (a, n, B [I])
Bb [I] = true;
}
// For each element in c, do a BS only if B [I] is true
For (int I = 0; I <n; I ++) // NlogN
{
If (B [I] & BinarySearch (a, n, c [I])
Return c [I];
}
Return-1; // not found
}
The code for sorting and binary search is as follows:
The code is as follows:
// Determine whether a contains value k
Bool BinarySearch (int * a, int n, int k)
{
Int left = 0;
Int right = n-1;
While (left <= right)
{
Int mid = (left + right );
If (a [mid] <k)
Left = mid + 1;
If (a [mid] = k)
Return true;
Else
Right = mid-1;
}
Return false;
}
// Compare function for qsort
Int compare (const void * a, const void * B)
{
Return * (int *) a-* (int *) B;
}
To sum up, you can solve the problem of searching in arrays in the following two situations:
If the given array is ordered, you should first think of Binary Search, which requires O (logn ).
If the given array is unordered, you should first sort the array. many sorting algorithms can sort the array within the O (nlogn) time, and then use the binary search, the total time complexity is still O (nlogn ).
If the above two points can be achieved, most of the array search problems can be solved.
Find the unique repeated element in the array
Given an array containing 1001 elements, which contains integers within 1-, only one integer is repeated. Please find this number.
Find the sum of the entire array, and subtract the sum of 1-. the code is omitted.
Find the element that appears an odd number of times
Given an integer array a containing n elements, only one element appears an odd number of times to find this element.
For any k, k ^ k = 0, k ^ 0 = k, so all elements in a are exclusive or, if the number of elements with an even number is exclusive or becomes 0, only the element with an odd number is left.
Int FindElementWithOddCount (int * a, int n)
{
Int r = a [0];
For (int I = 1; I
Evaluate the number pairs in the array that satisfy the given and
Given two ordered integer arrays a and B, each having n elements, find the number pairs that satisfy the given and given conditions in the two arrays, that is, for elements j in elements I and B in, meet I + j = d (d known ).
The two pointers I and j point to the beginning and end of the array respectively, and then traverse from both ends to the middle until the two pointers cross.
The code is as follows:
// Find the number pairs that meet the given and given conditions
Void FixedSum (int * a, int * B, int n, int d)
{
For (int I = 0, j = n-1; I <n & j> = 0)
{
If (a [I] + B [j] <d)
++ I;
Else if (a [I] + B [j] = d)
{
Cout <a [I] <"," <B [j] <endl;
++ I;
-- J;
}
Else // a [I] + B [j]> d
-- J;
}
}
Maximum child segment and
Given an integer array a, calculate the sum of the maximum continuous sub-segments. if the sum is negative, calculate by 0, such as 1, 2,-5, 6, 8: 6 + 8 = 14.
I will not talk about the classic questions on programming.
The code is as follows:
// The largest sum of sub-arrays
Int Sum (int * a, int n)
{
Int curSum = 0;
Int maxSum = 0;
For (int I = 0; I <n; I ++)
{
If (curSum + a [I] <0)
CurSum = 0;
Else
{
CurSum + = a [I];
MaxSum = max (maxSum, curSum );
}
}
Return maxSum;
}
Maximum child segment product
Given an integer that has enough a to obtain the product of the maximum continuous sub-segment, such as 1, 2,-8, 12, and 7, the output is 12*7 = 84.
Similar to the maximum Sub-Segment, pay attention to handling negative numbers.
The code is as follows:
// The maximum product of the sub-array
Int MaxProduct (int * a, int n)
{
Int maxProduct = 1; // max positive product at current position
Int minProduct = 1; // min negative product at current position
Int r = 1; // result, max multiplication totally
For (int I = 0; I <n; I ++)
{
If (a [I]> 0)
{
MaxProduct * = a [I];
MinProduct = min (minProduct * a [I], 1 );
}
Else if (a [I] = 0)
{
MaxProduct = 1;
MinProduct = 1;
}
Else // a [I] <0
{
Int temp = maxProduct;
MaxProduct = max (minProduct * a [I], 1 );
MinProduct = temp * a [I];
}
R = max (r, maxProduct );
}
Return r;
}
Array cyclic shift
Moving a k-bit array containing n elements cyclically to the right requires that the time complexity be O (n) and only two additional variables can be used, this is a question in the beauty of Microsoft's programming.
For example, if array 1 2 3 4 loop shifts 1 bit to 4 1 2 3, we can see that the order of 1 2 3 is not changed before and after the shift, but it is exchanged with the position of 4, so it is equivalent to dividing 1 2 3 4 into two parts first 1 2 3 | 4, then 1 2 3 backward order, and then 4 backward order to get 3 2 1 4, finally, the overall Reverse order is 4 1 2 3.
The code is as follows:
// Sort the elements between start and end in the buffer in reverse order
Void Reverse (int buffer [], int start, int end)
{
While (start <end)
{
Int temp = buffer [start];
Buffer [start ++] = buffer [end];
Buffer [end --] = temp;
}
}
// Shift the array buffer containing n elements to the right k bit
Void Shift (int buffer [], int n, int k)
{
K % = n;
Reverse (buffer, 0, n-k-1 );
Reverse (buffer, n-k, n-1 );
Reverse (buffer, 0, n-1 );
}
Reverse string order
Given a character array a containing n elements, sort it in reverse order.
You may think this is not about arrays, but about strings. Yes. But don't forget that the question requires reverse order, that is, extra space allocation is not allowed, so the parameter must be in the form of a character array, because the string cannot be modified (here only the string constant in C/C ++), it is related to the array, but not an integer array, but a character array. Use two pointers to point to the first of the character array, exchange the corresponding characters, and then move the two pointers to the center of the array until the intersection.
The code is as follows:
// Reverse string order
Void Reverse (char * a, int n)
{
Int left = 0;
Int right = n-1;
While (left <right)
{
Char temp = a [left];
A [left ++] = a [right];
A [right --] = temp;
}
}
Combination Problem
Given an integer array a containing n elements, take any m elements from it and obtain all the combinations. For example:
A = 1, 2, 3, 4, 5
M = 3
Output:
1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5
2 3 4, 2 3 5, 2 4 5
3 4 5
For typical arrangement and combination problems, the backtracking method is preferred. to simplify the problem, we set n element values in a to 1-n.
The code is as follows:
// N Select All m combinations
Int buffer [100];
Void PrintArray (int * a, int n)
{
For (int I = 0; I <n; ++ I)
Cout <a [I] <"";
Cout <endl;
}
Bool IsValid (int lastIndex, int value)
{
For (int I = 0; I <lastIndex; I ++)
{
If (buffer [I]> = value)
Return false;
}
Return true;
}
Void Select (int t, int n, int m)
{
If (t = m)
PrintArray (buffer, m );
Else
{
For (int I = 1; I <= n; I ++)
{
Buffer [t] = I;
If (IsValid (t, I ))
Select (t + 1, n, m );
}
}
}
Merge two arrays
Given two ordered (non-descending) integer arrays a and B containing n elements. To merge the elements in the two arrays to the integer array c, you must remove the repeated elements and keep the c order (non-descending ). Example:
A = 1, 2, 4, 8
B = 1, 3, 5, 8
C = 1, 2, 3, 4, 5, 8
Using the merge sort idea, the two pointers I, j, and k point to arrays a and B respectively, and then compare the sizes of the elements corresponding to the two pointers. There are three situations:
A [I]
If a [I] = B [j], c [k] is equal to a [I] or B [j.
A [I]> B [j], c [k] = B [j].
Repeat the above process until I or j reaches the end of the array, and then copy the remaining elements directly to array c.
The code is as follows:
// Merge two ordered arrays
Void Merge (int * a, int * B, int * c, int n)
{
Int I = 0;
Int j = 0;
Int k = 0;
While (I <n & j <n)
{
If (a [I] <B [j]) // if the element of a is small, insert the element from a to c
{
C [k ++] = a [I];
++ I;
}
Else if (a [I] = B [j]) // if elements a and B are equal, both can be inserted. Insert
{
C [k ++] = a [I];
++ I;
++ J;
}
Else // a [I]> B [j] // if the element in B is small, insert the element in B to c
{
C [k ++] = B [j];
++ J;
}
}
If (I = n) // if a finishes traversing, process the remaining elements in B.
{
For (int m = j; m <n; ++ m)
C [k ++] = B [m];
}
Else // j = n. If B finishes traversing, process the remaining elements in.
{
For (int m = I; m <n; ++ m)
C [k ++] = a [m];
}
}
Rescheduling
Given an integer array a containing n elements, which contains 0 and non-0 elements, sort the array. requirements:
After sorting, all 0 elements are in the front, all non-zero elements are in the back, and the relative positions of non-zero elements remain unchanged.
You cannot use additional storage space.
Example: input 0, 3, 0, 2, 1, 0, 0, output 0, 0, 0, 0, 3, 2, 1.
This sorting is non-traditional because it requires that the relative positions of non-zero elements remain unchanged before and after sorting, which may be more appropriate. We can traverse the entire array from the forward. if the element on position I is not 0, if a [k] is 0, assign a [I] to a [k] and a [k] to 0. In fact, I is a subscript of a non-0 element, while k is a subscript of A 0 element.
The code is as follows:
Void Arrange (int * a, int n)
{
Int k = n-1;
For (int I = n-1; I> = 0; -- I)
{
If (a [I]! = 0)
{
If (a [k] = 0)
{
A [k] = a [I];
A [I] = 0;
}
-- K;
}
}
}