例如:
[1,2,3] -> [2,4,6]
[9,1] -> [1,8,2]
[6,7,5] -> [1,3,5,0]
我昨天在第一次技术面试中得到了这个问题(在C中做过,因为那是我最好的语言,所以C答案会有所帮助)并完全消失:( 这就是我的想法:
从数组末尾开始并向左移动
在每{{}}},乘以2并查看是否有2位数(如果arr[i]
)并且如果有最左边的数字,请将其移至arr[i]/10 != 0
,只要arr[i-1]
。
我无法弄清楚如何在C中实际执行此操作。我有类似的事情:
a[i-1] != NULL
但是我的代码中存在很多错误。有没有更好的方法,还是我走在正确的轨道上?
答案 0 :(得分:1)
我能在短时间内思考,比如面试
#include <stdio.h>
#include <stdlib.h>
void invert (int *head, int *tail)
{
int temp;
if (head < tail)
{
temp = *head;
*head = *tail;
*tail = temp;
invert(++head, --tail);
}
}
int* multTwo(int* arr, size_t len)
{
int value = 0;
int n_digits =0 ;
// CONVERT THE ARRAY TO NUMBER
while(len--)
{
value += *arr;
value *=10;
arr++;
}
value /= 10;
// DOUBLE THE NUMBER
value *= 2;
// CONVERT IT TO BUFFER
int *digits = malloc(sizeof(*digits));
while ((value>0) && (digits != NULL))
{
digits[n_digits++] = value%10;
value /= 10;
digits = realloc( digits, sizeof(*digits) * (n_digits+1) );
}
if (digits != NULL)
{
invert(digits, &digits[n_digits-1]);
printf("[ ");
for (int i=0; i<n_digits; i++)
printf("%d, ", digits[i]);
printf("]\n");
}
return digits;
}
int main(void)
{
int array[] = {6,7,5};
multTwo(array, sizeof(array)/sizeof(array[0]));
return 0;
}
答案 1 :(得分:1)
一些伪代码。主要思想是将C知识的深度展示为面试的一部分,而非代码高尔夫。
什么签名?
// arr is not changed, use `const`
// array indexing best done with `size_t`
int* multTwo(const int* arr, size_t len) {
需要大小并显示错误处理。也许在arr == NULL
len > 0
need = len;
// if lead element is 5 or more, add 1.
// Error if element is not in 0-9 range
分配内存。分配给可变去引用类型的大小比编码变量类型更不容易出错,更容易查看和维护。在C面试中显示维护问题是一件很好的事情。考虑以后的代码是否更改为unsigned char* multTwo(const unsigned char* arr, size_t len) {
,无需更改newarr = malloc(sizeof *newarr * need)
。
newarr = malloc(sizeof *newarr * need)
检查分配。分配0可以返回NULL。然而,这个例程仍然应该分配1个字节,有点浪费,以确保NULL
返回是错误。与面试官讨论的问题很好。表明您希望清楚地了解客户的需求,不仅仅是功能,而是角落案例。
if (newarr == NULL && need > 0) fail()
循环并填充新数组,就像使用有意义的变量名称编码的OP并使用无符号数组索引一样。
size_t arr_i=len;
size_t newarr_i=need;
int carry = 0;
while (arr_i > 0)
sum = arr[--arr_i]*2 + carry;
newarr[--newarr_i] = sum%10;
carry = sum/10;
}
if (carry) {
newarr[--newarr_i] = carry;
}
返回newarr
答案 2 :(得分:1)
我首先要查看arr
中的第一个数字是否为5或更多,以检查newarr
数组是否需要比原始数组大1。
这样的初始化:
int* newarr;
int newlen;
if (*arr >= 5)
newlen = len + 1;
else
newlen = len;
newarr = (int*)malloc(sizeof(int) * newlen);
memset(newarr, 0, newlen); //initialize all newarr values to 0
现在显然我们现在必须进行乘法运算。为了得到1的数字,我们使用模运算符%
,为了获得10位数,我们使用除法运算符/
。当然,如果乘法值为10或更大,我们只需要进行除法。所以我们填充newarr
的循环看起来像这样:
int i, temp;
for (i = 1; i <= len; i++) {
temp = *(arr + i - 1) * 2;
if (temp < 10) {
*(newarr + i - 1) += temp;
}
else {
*(newarr + i - 1) += temp / 10; //inset 10's digit
*(newarr + i) += temp % 10; //inset 1's digit
}
}
所以我们的全部功能最终成为
#include <stdlib.h>
#include <string.h>
int* multTwo(int* arr, int len)
{
int* newarr;
int newlen;
if (*arr >= 5)
newlen = len + 1;
else
newlen = len;
newarr = (int*)malloc(sizeof(int) * newlen);
memset(newarr, 0, newlen); //initialize all newarr values to 0
int i, temp;
for (i = 1; i <= len; i++) {
temp = *(arr + i - 1) * 2;
if (temp < 10) {
*(newarr + i - 1) += temp;
}
else {
*(newarr + i - 1) += temp / 10; //insert 10's digit
*(newarr + i) += temp % 10; //inset 1's digit
}
}
return newarr; //don't forget to free once you're done with newarr!
}