第一题:数值的整数次方
需要注意的地方:指数为负数,指数为负数的时候,数值为0,首先给出一般性的解法:
//注意,判断浮点数是否相等,不能用==,而是差值在某个范围内 bool equal(double num1, double num2) { if (num1 - num2 > -0.0000001 && num1 - num2 < 0.0000001) return true; else return false; } double PowerWithUnsignedExponent(double base, unsigned int exponent) { double result = 1.0; for (int i = 1; i <= exponent; ++i) result *= base; return result; } double Power(double base, int exponent) { if (equal(base, 0.0) && exponent < 0) throw new exception("输入不合法"); unsigned int absExponent = (unsigned int)(exponent); if (exponent < 0) absExponent = (unsigned int)(-exponent); double result = PowerWithUnsignedExponent(base, absExponent); if (exponent < 0) result = 1 / result; return result; }书中给出了高效的解法:a^n=a^(n/2)*a^(n/2) 或者 a^n=a^((n-1)/2)*a^((n-1)/2)*a,利用这个式子,求解: double PowerWithUnsignedExponent(double base, unsigned int exponent) { if (exponent == 0) return 1; if (exponent == 1) return base; double result = PowerWithUnsignedExponent(base, exponent >> 1); result *= result; if (exponent & 0x1 == 1) result *= base; return result; } 第二题:打印1到最大的n位数这个题,注意很可能会溢出,所以用数组模拟加法来解。
bool Increment(vector<int> &number) { bool isOverflow = false; int nTakeOver = 0; int length = number.size(); for (int i = length -1; i >= 0; --i) { int nSum = number[i] + nTakeOver; if (i == length - 1) ++nSum; if (nSum >= 10) { if (i == 0) isOverflow = true; else { nSum -= 10; nTakeOver = 1; number[i] = nSum; } } else { number[i] = nSum; break; } } return isOverflow; } void PrintNumber(vector<int> &number) { int i = 0; while (i < number.size() && number[i] == 0) { ++i; } for (; i < number.size(); ++i) { cout << number[i]; } cout << "\n"; } void print1ToMaxNDigits(int n) { if (n <= 0) return; vector<int> number(n,0); while (!Increment(number)) PrintNumber(number); } 第三题:在O(1)时间内删除链表节点一种思路是两个节点,前后各一个。另一种思路是交换要删除的节点和后面的节点,然后删除后面的节点即可,第一种思路第一章总结过
第四题:调整数组顺序使奇数位于偶数前面
void RerderOddEven(vector<int> &nums) { int left = 0; int right = nums.size() - 1; while (left < right) { while (left < right && (nums[left] & 0x01) == 1) ++left; while (left < right && (nums[right] & 0x01) == 0) --right; if (left < right) swap(nums[left], nums[right]); } } 第五题:反转链表容易出错的题
ListNode* ReverseList(ListNode *pHead) { ListNode *pReversedHead = NULL; ListNode *pNode = pHead; ListNode *pPrev = NULL; while (pNode != NULL) { ListNode *pNext = pNode->next; if (pNext == NULL) pReversedHead = pNext; pNode->next = pPrev; pPrev = pNode; pNode = pNext; } return pReversedHead; } 第六题:合并两个排序的链表非递归解:
ListNode* Merge(ListNode*pHead1, ListNode*pHead2) { ListNode *newList = NULL; if (pHead1 == NULL) return pHead2; if (pHead2 == NULL) return pHead1; if (pHead1->val < pHead2->val) { newList = pHead1; pHead1 = pHead1->next; } else { newList = pHead2; pHead2 = pHead2->next; } ListNode *pNode = newList; while (pHead1 != NULL && pHead2 != NULL) { if (pHead1->val < pHead2->val) { pNode->next = pHead1; pNode = pHead1; pHead1 = pHead1->next; } else { pNode->next = pHead2; pNode = pHead2; pHead2 = pHead2->next; } } if (pHead1 == NULL) pNode->next = pHead2; else pNode->next = pHead1; return newList; }递归解,简洁多了: ListNode *Merge(ListNode *pHead1, ListNode *pHead2) { ListNode *newList = NULL; if (pHead1 == NULL) return pHead2; if (pHead2 == NULL) return pHead1; if (pHead1->val < pHead2->val) { newList = pHead1; newList->next = Merge(pHead1->next, pHead2); } else { newList = pHead2; newList->next = Merge(pHead1, pHead2->next); } return newList; }