1. Find two numbers that appear only once in the array.

1) Question: Except for two numbers in an integer array, other numbers appear twice.

Write a program to find the numbers that appear only once. Requirements**The time complexity is****O (N)**,**The spatial complexity is****O (1)**

For example: A [] = {, 3,}; you need to find 5 and 6

2) analysis: the nature of an exclusive or operation: Any number exclusive or equal to 0. For each number in an array, the result is the exclusive or of two numbers that appear only once. All the numbers that appear twice are offset in the exclusive or.

If you can divide the original array into two subarrays. Each sub-array contains a number that appears only once, and other numbers appear twice. In this way, the original number group is split from start to end, or each number in the array. The final result is the difference or result of two numbers that only appear once.

How to split an array?

Because these two numbers are certainly different, the difference or result is certainly not 0, that is, at least one of the binary representation of the result number is 1.

1> In the result number, we find the position of the first digit as 1, which is recorded as the nth digit.

2> divide the numbers in the original array into two subarrays based on whether the nth bit is 1. the nth bit of each number in the first subarray is 1, the Nth digit of each number in the second sub-array is 0.

3> now we have made the original number group into two sub-arrays. Each sub-array contains a number that appears only once, and its number appears twice. So far, all the problems have been solved.

3) source code:

# Include <iostream> using namespace STD; int findfirstone (INT value); bool testbit (INT value, int POS); int findnums (INT date [], int length, int & num1, Int & num2) {If (length <2) Return-1; int ansxor = 0; For (INT I = 0; I <length; I ++) ansxor ^ = date [I]; // unique or Int Pos = findfirstone (ansxor); num1 = num2 = 0; For (INT I = 0; I <length; I ++) {If (testbit (date [I], POS) // if this bit is 1 num1 ^ = date [I]; else num2 ^ = date [I];} return 0;} int Findfirstone (INT value) {// obtain the first position in the binary value, int Pos = 1; while (Value & 1 )! = 1) {value = value> 1; POS ++;} return Pos;} bool testbit (INT value, int POS) {// test whether a position is 1 return (value> POS) & 1);} int main (void) {int date [10] = {1, 2, 4, 4, 5, 6, 4, 3, 2, 1}; int ans1, ans2; If (findnums (date, 10, ans1, ans2) = 0) cout <ans1 <"" <ans2 <Endl; else cout <"error" <Endl; return 0 ;}

2. Find the first public node of the linked list

1) Question: two one-way linked lists to find their first public node.

The linked list node is defined:

Struct listnode

{

Int data;

Listnode * m_pnext;

};

2) Analysis:

1) If two linked lists intersect, the nodes are the same starting from the intersection, that is, the last node must be the same;

2) traverse two linked lists from the beginning to the end and record the length of the linked list. If the end nodes of the two are different, the two are definitely not intersecting;

3) The tail node is the same, if A is LA, B is LB, if LA> LB, a first LA-LB first skips, and then both traverse backward until the same node is encountered; similar processing of La <lb

The distance between the first common node and the Start Node is La-start_a = LB-start_ B.

3) source code:

#include <iostream>using namespace std; struct ListNode{ int data; ListNode *m_pNext;};unsigned int ListLength(ListNode* pHead){ unsigned int nLength = 0; ListNode* pNode = pHead; while(pNode != NULL) { ++ nLength; pNode = pNode->m_pNext; } return nLength;}ListNode * FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2){ // Get the length of two lists unsigned int nLength1 = ListLength(pHead1); unsigned int nLength2 = ListLength(pHead2); int nLengthDif = nLength1 - nLength2; // Get the longer list ListNode *pListHeadLong = pHead1; ListNode *pListHeadShort = pHead2; if(nLength2 > nLength1) { pListHeadLong = pHead2; pListHeadShort = pHead1; nLengthDif = nLength2 - nLength1; } // Move on the longer list for(int i = 0; i < nLengthDif; ++ i) pListHeadLong = pListHeadLong->m_pNext; // Move on both lists while((pListHeadLong != NULL) && (pListHeadShort != NULL) && (pListHeadLong != pListHeadShort)) { pListHeadLong = pListHeadLong->m_pNext; pListHeadShort = pListHeadShort->m_pNext; } // Get the first common node in two lists ListNode *pFisrtCommonNode = NULL; if(pListHeadLong == pListHeadShort) pFisrtCommonNode = pListHeadLong; return pFisrtCommonNode;}

3. delete a specific character from the string.

1) Question: enter two strings to remove all the characters from the first string.

For example, if you enter "they are students." and "aeiou", the first string after deletion becomes "Thy R stdnts .".

2) Analysis:

1) first process string 2 ("aeiou") and traverse the string. If yes, hashtable [] = 1

2) Policy 1: searches for hashtable for every traversal of string 1. Delete an array if it exists (the complexity of array deletion is high)

Policy 2: Use two pointers to point to string 1. The current position of the character to be saved in the begin record. End is used to check whether hashtable exists. If the character indicated by end appears, it is skipped (not saved). Otherwise, it is saved to the position indicated by begin, then, begin ++, and finally begin = '\ 0 '.

3) source code:

# Include <stdio. h> # include <memory. h> int delchar (char * SRC, char * DST) {char * begin = SRC; char * end = SRC; char hashtable [256]; int I = 0; memset (hashtable, 0, sizeof (hashtable); // initialize each value in hashtable to 0 while (* DST) // traverse DEST and mark each character that appears + + hashtable [* DST ++]; /* the position where the begin record is to be saved. The End record is to be saved. If the character indicated by end appears in string 2, skip (do not save). Otherwise, it is saved to the position indicated by begin, then begin ++ */while (* End) {If (! Hashtable [* end]) // If {* begin = * end; ++ begin;} + + end;} * begin = '\ 0';} int main () {char SRC [] = "they are students. "; char del [] =" aeiou "; delchar (SRC, del); printf (" output: % s \ n ", Src); Return 0 ;}

4. Search for ugly data.

1) Question: The numbers that only contain factors 2, 3, and 5 are called the ugly number ). For example, values 6 and 8 are ugly, but 14 is not because it contains factor 7. In habits, we regard 1 as the first ugly number. Calculate the number of ugliness in the ascending order.

2) Analysis:

Train of Thought 1: judge whether each number is an ugly number from 1. If yes, Count ++ will output this number until COUNT = 1500.

Disadvantage: Every number must be traversed, with a high time complexity.

Thought 2: Just traverse every ugly number

Let's assume that there are already several ugly numbers in an array, and these ugly numbers are arranged in order. We record the largest ugly number as Max, then the next ugly number must be the first ugly number multiplied by 2, 3, and 5.

Multiply by 2: multiply each number in the array by 2. Because the original array is ordered, because after multiply by 2, it is also orderly increasing, so there must be a number m2, each number in front of it is smaller than or equal to Max, while the number in the back of M2 is greater than Max, because we still need to keep the ascending order, so we take the first m2.

Multiply by 3: You can obtain the first number m3 greater than Max.

Multiply by 5: Use the first number M5.

The next ugly number is min {M2, M3, M5 }.

Pmultiply2, * pmultiply3, and * pmultiply5 are saved respectively. Multiply the base number to obtain the subscript of the ugly number array closest to the maximum value of the ugly number array.

3) source code:

**First:**

// The main program has two algorithms. // The first algorithm is very simple. It starts from 1 and takes a long time. // The second algorithm eliminates the need to judge whether it is not an ugly number, but it crashed at 1690... # Include "iostream" # define max_num 10 bool isuglynum (long number) {long num = number; while (0 = num % 2) {num = num/2 ;} while (0 = num % 3) {num = num/3;} while (0 = num % 5) {num = num/5 ;} if (num = 1) {// printf ("% d", number); Return true;} elsereturn false;} void getuglynumfunc1 () {Long Count = 0; // The number of uglynumlong I = 1; // For (long I = 1; I <= max_num; I ++) while (count <max_num) {If (isuglynum (I) Count ++; I ++;} printf ("\ n func1: The % d uugly number is % d", max_num, I-1 );} int main () {getuglynumfunc1 ();}

// The main program has two algorithms. // The first algorithm is very simple. It starts from 1 and takes a long time. // The second algorithm eliminates the need to judge whether it is not an ugly number, but it crashed at 1690... # Include "iostream" # define max_num 10 long min (long number1, long number2, long Number3) {long min = (number1 <number2 )? Number1: number2; min = (Min <Number3 )? Min: Number3; return min;} long _ getuglynumfunc2 (long index) {If (index <= 0) return 0; long * puglynumbers = new long [Index]; puglynumbers [0] = 1; long nextuglyindex = 1; // number of long * pmultiply2 = puglynumbers; long * counts = puglynumbers; while (nextuglyindex <index) {long min = min (* pmultiply2 * 2, * pmultiply3 * 3, * pmultiply5 * 5); // puglynumbers [nextuglyindex] = min; while (* pmultiply2) * 2 <= puglynumbers [nextuglyindex]) + pmultiply2; // The next ugly number subscript while (* pmultiply3) * 3 <= puglynumbers [nextuglyindex]) + + pmultiply3; // The next ugly number subscript while (* pmultiply5) * 5 <= puglynumbers [nextuglyindex]) + + pmultiply5; // The next ugly number subscript ++ nextuglyindex ;} long uugly = puglynumbers [nextuglyindex-1]; Delete [] puglynumbers; return uugly;} int main () {long max_uglynum = _ getuglynumfunc2 (max_num); printf ("\ n func2: the % d uugly number is % d \ n ", max_num, max_uglynum );}

5. Output from 1 to n

Number of digits

1) Question: Enter the number N and output the n-digit 10 from 1 to the maximum in order.

Base number. For example, input 3 outputs 1, 2, and 3.

, 4 ...... 999.

2) Analysis: This is an interesting question. It looks very simple, but there are actually a lot of xuanjicang in it.

Thought 1: Using Integer notation

Disadvantage: overflow occurs when the integer is exceeded.

void Print1ToMaxOfNDigits1(int n){int number=1;int i=0;while(i++<n)number*=10;for(i=1; i<number; i++)cout<<i<<" ";}

Train of Thought 2: Simulate addition and subtraction using strings

When using a string to express a number, the most intuitive way is that each character in the string is a character between '0' and '9', indicating a digit in the number. Because the maximum number is n digits, we need an n + 1 character string (the last digit is the ending symbol '\ 0 '). When the actual number is less than N digits, the first half of the string is zero. In this way, the digits are always at the end of the string (excluding the ending symbol ).

First, we initialize each digit in the string to '0 '. Add 1 to the number expressed in the string each time, and then output.

Therefore, we only need to do two things: first, simulate addition on numbers expressed in strings. In addition, we need to output the numbers expressed in strings. It is worth noting that when the number is less than N digits, we add zero before the number. 0 of these complement BITs should not be output during output. For example, when 3 is input, the number 98 is output in the form of 098, which is not in our habit.

# Include <iostream> using namespace STD; bool increment (char * Number) {bool isoverflow = false; int ntakeover = 0; int nlength = strlen (number ); for (INT I = nLength-1; I> = 0; I --) {int nsum = number [I]-'0' + ntakeover; if (I = nLength-1) nsum ++; If (nsum> = 10) {if (I = 0) isoverflow = true; else {nsum-= 10; ntakeover = 1; number [I] = '0' + nsum;} else {number [I] = '0' + nsum; break;} return isoverflow ;} void printnumber (char * Number) {bool isbeginn Ing0 = true; int nlength = strlen (number); For (INT I = 0; I <nlength; I ++) {If (isbeginning0 & number [I]! = '0') // if the first one is 0, then judge whether the next one is 0 isbeginning0 = false; If (! Isbeginning0) cout <number [I];} cout <";} void print1tomaxofndigits2 (INT N) {If (n <= 0) return; char * number = new char [n + 1]; memset (number, '0', n); number [N] = '\ 0'; while (! Increment (number) {printnumber (number) ;}cout <Endl; Delete [] Number ;}int main () {print1tomaxofndigits2 (2 );}

Thought 3: Calculate the n-digit 0 ~ 9 In full order

The second approach basically corresponds to the first approach, but replaces an integer value with a string representation. The second method is intuitive, but the code is a little long because it simulates the addition of integers. It is not easy to write such a long code in just a few minutes during the interview. Next we will consider this issue with another idea. If we add 0 in front of the number, we will find that all the 10 hexadecimal numbers of N digits are actually N in the full order from 0 to 9. That is to say, we arrange each digit of a number from 0 to 9 and get all the 10-digit numbers. It's just that when we are outputting, we will not output the number 0 at the top.

The full permutation is easily expressed by recursion. Each digit of a number may be a number between 0 and 9, and the next digit is set. The condition for Recursive termination is that we have set the last digit of the number.

#include <iostream>using namespace std; void PrintNumber(char* number){bool isBeginning0=true;int nLength=strlen(number);for(int i=0; i<nLength; i++){if(isBeginning0 && number[i]!='0')isBeginning0=false;if(!isBeginning0){cout<<number[i];}}cout<<" ";}void Print1ToMaxOfNDigitsRecursively(char *number, int length, int index){if(index==length-1){PrintNumber(number);return;}for(int i=0; i<10; i++){number[index+1]=i+'0';Print1ToMaxOfNDigitsRecursively(number, length, index+1);}}void Print1ToMaxOfNDigit3(int n){if(n<0)return;char *number=new char[n+1];number[n]='\0';for(int i=0; i<10; i++){number[0]=i+'0';Print1ToMaxOfNDigitsRecursively(number, n, 0);}}int main(){Print1ToMaxOfNDigit3(2); }