Skip to content

Latest commit

 

History

History
172 lines (128 loc) · 6.32 KB

arts-0008.md

File metadata and controls

172 lines (128 loc) · 6.32 KB

1.Algorithm

[6]  ZigZag Conversion

Medium    String

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P A H N A P L S I I G Y I R

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

string convert(string s, int numRows);

Example1:

 Input: s = "PAYPALISHIRING", numRows = 3
 Output: "PAHNAPLSIIGYIR"

Example2:

 Input: s = "PAYPALISHIRING", numRows = 4
 Output: "PINALSIGYAHRPI"
 Explanation:

 P     I    N
 A   L S  I G
 Y A   H R
 P     I

解答 本题主要是理解转换后的多维数组的下标对应关系

(1).常规解法,时间复杂度 O(n), 空间复杂度 O(n)
func convert(s string, numRows int) string {
	if len(s) == 0 || numRows == 0 || numRows == 1 {
		return s
	}

	rows := min(len(s), numRows)
	retVals := make([]string, rows)

	curRow, goingDown := 0, false
	for i := range s {
		retVals[curRow] += string(s[i : i+1])
		if curRow == 0 || curRow == rows-1 {
			goingDown = !goingDown
		}

		if goingDown {
			curRow++
		} else {
			curRow--
		}
	}

	vals := ""
	for _, val := range retVals {
		vals += val
	}
	return vals
}

func min(val1, val2 int) int {
	if val1 < val2 {
		return val1
	}
	return val2
}
(2).寻找数组的位置下标关系
// line 0: indexK = 2 * numRows -2
// numRows -1, indexK = k(2*numRows-2) + numRows -1
// line i: k, 2 * numRows -2 + i  or  (k+1)(2*numRows-2)
/*n=numRows
Δ=2n-2    1                           2n-1                         4n-3
Δ=        2                     2n-2  2n                    4n-4   4n-2
Δ=        3               2n-3        2n+1              4n-5       .
Δ=        .           .               .               .            .
Δ=        .       n+2                 .           3n               .
Δ=        n-1 n+1                     3n-3    3n-1                 5n-5
Δ=2n-2    n                           3n-2                         5n-4
*/
func convert1(s string, numRows int) string {
	if len(s) <= numRows || numRows == 1 {
		return s
  }

	period := 2*numRows - 2
	res := make([]string, numRows)

	for i, v := range s {
		mod := i % period
		// fmt.Printf("i: %d, mod: %d, period: %d\n",i, mod, period)
		if mod < numRows {
			res[mod] += string(v)
		} else {
			res[period-mod] += string(v)
		}
	}
	return strings.Join(res, "")
}

2.Review

The most important skill a programmer can learn

  • No, no, no, no, and no. And no. A big NO. Clear as that.
  • As a programmer, writing code is the biggest part of your job.
  • Knowing when not to code is possibly the most important skill a programmer can learn. — The Art Of Readable Code
  • Every line of code you write is:
    • code that has to be read and understood by other programmers
    • code that has to be tested and debugged
    • code that will increase defects in your software
    • code that probably will introduce new bugs in the future
  • The best code is no code at all, and the most effective programmer is the one who knows when not to code.
  • Understanding the purpose of your software and its core definition is the first step to know when not to code.
  • Knowing when not to code keeps your codebase small.
  • One of my most productive days was throwing away 1000 lines of code. — Ken Thompson
  • Keep coding but know when to say no to coding.

Difference between malloc and calloc? Why does calloc exist?

  • calloc() gives you a zero-initialized buffer, while malloc() leaves the memory uninitialized.
void* buffer1 = malloc(size);
void* buffer2 = calloc(count, size);

void* buffer3 = malloc(count * size);
memset(buffer3, 0, count * size);

3.Tip

这周工作主要遇到两个问题,这两个问题我觉得非常有必要进行重视。

对需求的理解和梳理,要进行反复确认

这周评审我们之前做的一个创新项目,去年一直是以创新项目的角色进行推进,今年想进行重新梳理,以工程化生产标准对接到我们的大平台里。由于关联几个团队,有的人急于推进整个项目,因此就先单独将底层的人工智能算法进行了工程化,对所有单个接口进行了封装输出等。 但是当我参与完整个上层的需求评审后,发现一个非常大的问题,因为上层只是基于用户配置的模板进行输出,按实际情况不应该单独让上层去解析用户的配置模板再去进行算法方法的对应,如果这样做的话,就会导致一个模板功能中,一个输入文本参数会进行多次网络来回调用,导致整个程序的效率非常低。

总结:理解,梳理需求,而不能单独的是为了做功能而做功能,要理解整个需求的出发点,再结合需求,技术,实现人力资源及各个参与方的情况,进行综合评估,而不能孤立的去为了摊人力而做事情。

重视代码,不要轻易加入测试代码

周末遇到业务方反馈一个API的接口调用做了每日次数限制。这个限制当时是一个口述的需求,也只是为了限制体验用户的试用。而这次上线竟然将这个测试功能发布到生产了,因此只能进行功能的紧急修复。幸好回滚修复的流程还比较顺,对整个业务没有造成大的影响。

总结:不能轻易答应别人的需求,及时是简单的需求,几行代码就可以搞定等。要多考虑下,分析需求的合理性,是不是有其他更好的解决方案,比如需求只是在测试环境上有效,那如果加上这个功能,对生产环境是否有影响?多套环境之间如何进行同步,保证功能的完整性等。

4.Share

如何选择开源许可证? free-software-licenses

Best Practices for API Error Handling