编程出错问题-算法方法

1、关于size: 

最好不要用for(i = 0; i <a.size();i++),而用for(i = 0 ; i <size;i++),因为a.size(),对于数据结构来说,运行过程中可能会改变大小,比如栈会出栈入栈。所以用变量存储初始大小。

2、关于矩阵

顺时针旋转:沿左斜轴翻转,再沿竖中轴线翻转。

for i = 0 to size

        for j = i+1 to size 

                 array[i][j] = array[j][i]

for i = 0 to size

        for j = 0 to size>>1        注意这里没有等号,如果有等号在偶数层多翻转一次。

                 array[i][j] = array[i][size - 1 - j]

同理,顺时针旋转:沿右斜轴翻转,再沿竖中轴线翻转。

顺时针180:直接沿横中轴翻转即可。

3、螺旋矩阵

用四个变量标志上下左右的限,限的改变意味着转向。而用另外的变量作为遍历变量。

up = 0, down = n - 1,left = 0, right = n - 1,number = 1

while(number<= n*n)

        for(j = left :right)        //右侧有等号

                array[up][j] = number++

        up++

        for(i = up : down)        //有等号 

                 array[i][right] = number++

        right--

        for(j = right : left)

                array[down][j] = number++

        down--

        for(i = down : up)

                array[i][left] = number++

        left++

4、矩阵

从左下或右上开始,只需要O(m+n)的时间复杂度。 

5、Trie树

struct Trie

{

vector<Trie*> children;//每个节点预备26个指针,分别指向26个字符;

bool isEnd;//该节点是否为end节点?即,该串是否contian?

}

Trie():

insert(word)

{        Trie* node = this;

        for auto c: word

                if(node->children[c-'a'] =NULL)        node->children[c-'a'] = new Trie();//需要将字符新建一下

                node = node->children[c-'a']

        node->isEnd = true//否则会把初始节点的isEnd设为true

}

search(word)

{

        Trie* node = this;

        for auto c: word

                if(node->children[c-'a'] =NULL)        return false;//需要将字符新建一下

                node = node->children[c-'a']

      return  node->isEnd = true//否则会返回初始节点的isEnd

        //如果是找prefix,直接 return true即可。

}

6、最长回文子串

出现偶数字的字符;出现奇数次字符,其频次为1;

7、找环形链表入口:

快慢指针,fast 、 slow重合时不一定为入口,根据计算,重合地举例链表入环点(b-a)处。

p=head

while(p!=fast)

        p = p->next,fast = fast->next;

//p走长度a,fast走长度a,刚好重合

8、链表:两数相加

while(l1||l2)

{

        a = 0 or l1.val

        b = 0 or l2.val

        number  = a+b+c

        c= number/10

        number = number%10

        if(head == NULL)       

                head = tail = new(number)

        else

                tail->next = new (number)

                tail = tail->next

}

if(c)        tail = new (c)

9、链表相交

        while(p!=q)

                if(p==NULL)        p = headB;

                else        p =  p->next;

                if(q==NULL)        q = headA;

                else        q = q->next;

注意p = p->next是else的情况下,也就是,转向也等同于是next;

10、string s ="i am a pretty gril."按空格划分的方法:

stringstram s_stream(s);

vector<string> a;

string temp;

while(getline(s_stream,temp,' '))

        a.push_back(temp);

注意:这里需要两个map。如果是一个char->string的映射可能会存在误判。 

11、

放一个stack记录整个链表指针,每次从顶端弹出一个顶点,用于记录当前未排序的末尾节点。

while(i<size/2)

        next=p->next

       top=stack.top()

        if(top == next)

                next->next =NULL;        

                return;

        p->next = top

        top->next = next

        p = next

endwhile

  if(size%2)      p->next = NULL

注意奇偶个数不同,循环结束条件不同

12、迭代器删除

for(auto it = s.begin();it!=s.end();)

        if(*it == ' ')

                s.erase(it);

        else

                it++;

注意这里,for循环没有每次执行it++,而是把it++放在循环体内部。

13、关于堆:

如果index是从0开始,那么堆应该是i,2*i+1和2*i+2

void build(int[] nums,int heapsize)

        for(i = heapsize/2 -1 ;i>=0;i--)

                heaply(nums,i,heapsize)

void heaply(int [] nums,int i,int heapsize)//从位置i开始的父子节点一定满足堆关系

        int left = i*2+1,right = i*2+2,big = i;

        while true

                if(left<heapsize&&nums[left]>nums[big])

                        big = left

                if(right<heapsize&&nums[right]>nums[big])

                        big = right

                if(big!=i)

                        swap(nums[big],nums[i])

                        i = big

                else

                        break

void findTopK(int nums,int size,int k)//

        for(int i = 0 ; i<k-1;i++)//注意这里是<k-1,如果是top1不需要删除,所以第k大需要删除k-1个

                size --

                swap(nums[0],nums[i])

                heaply(nums,0,size)

        return nums[0]

14、回溯的其他方法:

size = nums.size()

vector<int> temp;

for(mask  = 0 :(1<<size))

         for(i  = 0 :size)

                if(mask&(1<<i))

                        temp.push_back(nums[i]);

        result.push_back(temp);

15、Boyer-Moore

找非负数组元素中过半元素,用一个count记录当前出现次数

int count  = 0,result = -1

for(i : nums)//nums是数组

        if(i == result)        count++;

        else if(--count < 0 )        count = 1,candidate = i;

16、堆

pritority_queue qe;

sum = 0,ans = 0;

for(i:nums)

        sum+=i

        if(i<0)

               qe.push(-i)

                if( sum < 0)

                        sum+=qe.top();

                        qe.pop();

                        ans++;

17、取反思想

 for (i:nums)

        temp+=i

        if(map.count(temp - k)!=0)        result+=map[temp-k];

         map[temp-k]++;

18、进制转换

 问:给定rand函数是从1~7的随机数,如何生成1~10的随机数

用两个1~7的随机数生成2位7进制数,将其转换为10进制,也就是00~48。舍弃末尾的9位后,对00~39取余即可。

同理:用k进制的随机数生成m进制的随机数:看几位k进制可以包含m,再转换为m进制后舍弃部分并取余即可。

19、图-用入度出度解决问题:

20、用分半的思想(或者还是说更合适)

用两个优先队列。priority_queue<int,vector<int>,greater<int>>表示按从大到小排列的数据,存放较小的数据。而priority_queue<int,vector<int>,less<int>>表示从小到大排列的数据,存放较大的数据。

如果两个队列的大小相等,那么中位数是两个队列的top/2;如果两个队列大小不等,在较大的队列的头部。

21、

 在数据量较大时,如果一个一个用f(n-1)*x时一定会超时。

做法:考虑特殊情况(例如n为-2147483648),此外用n每个2进制位计算结果的幂;

n =(n<0)? -n : n

result = 1

while(n)

        if(n%2)        result*=x

        x*=x

        n>>=1

return result或者1.0/result

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值